///< aliases to base ctors when possible.
CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled.
CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names.
-CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled.
+ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
+
CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory.
CODEGENOPT(DiscardValueNames , 1, 0) ///< Discard Value Names from the IR (LLVMContext flag)
CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing.
ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
/// Replace certain message sends with calls to ObjC runtime entrypoints
CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1)
-CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
- ///< enabled.
VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
enum SignReturnAddressKeyValue { AKey, BKey };
+ enum class FramePointerKind {
+ None, // Omit all frame pointers.
+ NonLeaf, // Keep non-leaf frame pointers.
+ All, // Keep all frame pointers.
+ };
+
/// The code model to use (-mcmodel).
std::string CodeModel;
HelpText<"The code model to use">, Values<"tiny,small,kernel,medium,large">;
def mdebug_pass : Separate<["-"], "mdebug-pass">,
HelpText<"Enable additional debug output">;
-def mdisable_fp_elim : Flag<["-"], "mdisable-fp-elim">,
- HelpText<"Disable frame pointer elimination optimization">;
+def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
+ HelpText<"Specify which frame pointers to retain (all, non-leaf, none).">, Values<"all,non-leaf,none">;
def mdisable_tail_calls : Flag<["-"], "mdisable-tail-calls">,
HelpText<"Disable tail call optimization, keeping the call stack accurate">;
def menable_no_infinities : Flag<["-"], "menable-no-infs">,
def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>;
def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>;
def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>,
- HelpText<"Omit frame pointer setup for leaf functions">, Flags<[CC1Option]>;
+ HelpText<"Omit frame pointer setup for leaf functions">;
def moslib_EQ : Joined<["-"], "moslib=">, Group<m_Group>;
def mpascal_strings : Flag<["-"], "mpascal-strings">, Alias<fpascal_strings>;
def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>;
if (!CodeGenOpts.TrapFuncName.empty())
FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName);
} else {
- // Attributes that should go on the function, but not the call site.
- if (!CodeGenOpts.DisableFPElim) {
- FuncAttrs.addAttribute("no-frame-pointer-elim", "false");
- } else if (CodeGenOpts.OmitLeafFramePointer) {
- FuncAttrs.addAttribute("no-frame-pointer-elim", "false");
- FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");
- } else {
- FuncAttrs.addAttribute("no-frame-pointer-elim", "true");
- FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf");
+ StringRef FpKind;
+ switch (CodeGenOpts.getFramePointer()) {
+ case CodeGenOptions::FramePointerKind::None:
+ FpKind = "none";
+ break;
+ case CodeGenOptions::FramePointerKind::NonLeaf:
+ FpKind = "non-leaf";
+ break;
+ case CodeGenOptions::FramePointerKind::All:
+ FpKind = "all";
+ break;
}
+ FuncAttrs.addAttribute("frame-pointer", FpKind);
FuncAttrs.addAttribute("less-precise-fpmad",
llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
#include "InputInfo.h"
#include "PS4CPU.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"
return codegenoptions::LimitedDebugInfo;
}
-enum class FramePointerKind { None, NonLeaf, All };
-
static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
switch (Triple.getArch()){
default:
return true;
}
-static FramePointerKind getFramePointerKind(const ArgList &Args,
- const llvm::Triple &Triple) {
+static CodeGenOptions::FramePointerKind
+getFramePointerKind(const ArgList &Args, const llvm::Triple &Triple) {
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);
if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
options::OPT_mno_omit_leaf_frame_pointer,
Triple.isPS4CPU()))
- return FramePointerKind::NonLeaf;
- return FramePointerKind::All;
+ return CodeGenOptions::FramePointerKind::NonLeaf;
+ return CodeGenOptions::FramePointerKind::All;
}
- return FramePointerKind::None;
+ return CodeGenOptions::FramePointerKind::None;
}
/// Add a CC1 option to specify the debug compilation directory.
if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
CmdArgs.push_back("-fdefault-calling-conv=stdcall");
- FramePointerKind FPKeepKind = getFramePointerKind(Args, RawTriple);
- if (FPKeepKind != FramePointerKind::None) {
- CmdArgs.push_back("-mdisable-fp-elim");
- if (FPKeepKind == FramePointerKind::NonLeaf)
- CmdArgs.push_back("-momit-leaf-frame-pointer");
+ CodeGenOptions::FramePointerKind FPKeepKind =
+ getFramePointerKind(Args, RawTriple);
+ 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);
+
if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
options::OPT_fno_zero_initialized_in_bss))
CmdArgs.push_back("-mno-zero-initialized-in-bss");
}
if (Arg *A = Args.getLastArg(options::OPT_pg))
- if (FPKeepKind == FramePointerKind::None)
+ if (FPKeepKind == CodeGenOptions::FramePointerKind::None)
D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer"
<< A->getAsString(Args);
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
Opts.CodeModel = TargetOpts.CodeModel;
Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
- Opts.DisableFPElim =
- (Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg));
+
+ // Handle -mframe-pointer option.
+ if (Arg *A = Args.getLastArg(OPT_mframe_pointer_EQ)) {
+ CodeGenOptions::FramePointerKind FP;
+ StringRef Name = A->getValue();
+ bool ValidFP = true;
+ if (Name == "none")
+ FP = CodeGenOptions::FramePointerKind::None;
+ else if (Name == "non-leaf")
+ FP = CodeGenOptions::FramePointerKind::NonLeaf;
+ else if (Name == "all")
+ FP = CodeGenOptions::FramePointerKind::All;
+ else {
+ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+ Success = false;
+ ValidFP = false;
+ }
+ if (ValidFP)
+ Opts.setFramePointer(FP);
+ }
+
+ // -pg may override -mframe-pointer
+ // TODO: This should be merged into getFramePointerKind in Clang.cpp.
+ if (Args.hasArg(OPT_pg))
+ Opts.setFramePointer(CodeGenOptions::FramePointerKind::All);
+
Opts.DisableFree = Args.hasArg(OPT_disable_free);
Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names);
Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls);
Opts.PIECopyRelocations =
Args.hasArg(OPT_mpie_copy_relocations);
Opts.NoPLT = Args.hasArg(OPT_fno_plt);
- Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer);
Opts.SaveTempLabels = Args.hasArg(OPT_msave_temp_labels);
Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
// REQUIRES: msp430-registered-target
-// RUN: %clang_cc1 -mdisable-fp-elim -triple msp430 -S %s -o - | FileCheck %s --check-prefix=FP_ENFORCED
+// RUN: %clang_cc1 -mframe-pointer=all -triple msp430 -S %s -o - | FileCheck %s --check-prefix=FP_ENFORCED
// RUN: %clang_cc1 -triple msp430 -S %s -o - | FileCheck %s --check-prefix=FP_DEFAULT
// Check the frame pointer is not used on MSP430 by default, but can be forcibly turned on.
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O3 -pg -S -o - %s | \
// RUN: FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O3 -momit-leaf-frame-pointer -pg -S -o - %s | \
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O3 -mframe-pointer=all -pg -S -o - %s | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O3 -mframe-pointer=non-leaf -pg -S -o - %s | \
// RUN: FileCheck %s
// Test that the frame pointer is kept when compiling with
return (char)-1;
}
-// CHECK: "no-frame-pointer-elim"="false"
-// CHECK-NOT: "no-frame-pointer-elim-non-leaf"
+// CHECK: "frame-pointer"="none"
};
C c;
-// CHECK: "no-frame-pointer-elim"="false"
-// CHECK-NOT: "no-frame-pointer-elim-non-leaf"
+// CHECK: "frame-pointer"="none"
// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fexceptions %s -o - |FileCheck %s
// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck -check-prefix CHECK-NOEXC %s
-// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm \
-// RUN: -momit-leaf-frame-pointer -mdisable-fp-elim %s -o - \
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -mframe-pointer=non-leaf %s -o - \
// RUN: | FileCheck -check-prefix CHECK-FP %s
struct A {
// PR21811: attach the appropriate attribute to the global init function
// CHECK-FP: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUX:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
-// CHECK-FP: attributes [[NUX]] = { noinline nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} }
+// CHECK-FP: attributes [[NUX]] = { noinline nounwind {{.*}}"frame-pointer"="non-leaf"{{.*}} }
-// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fobjc-runtime=ios-6.0 -Os -S -emit-llvm -o - %s -mdisable-fp-elim | FileCheck %s
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fobjc-runtime=ios-6.0 -Os -S -emit-llvm -o - %s -mframe-pointer=all | FileCheck %s
struct S {
S() = default;
// RUN: %clang_cl /Os --target=i686-pc-windows-msvc -### -- %s 2>&1 | FileCheck -check-prefix=Os %s
// RUN: %clang_cl /Os --target=x86_64-pc-windows-msvc -### -- %s 2>&1 | FileCheck -check-prefix=Os %s
-// Os-NOT: -mdisable-fp-elim
-// Os-NOT: -momit-leaf-frame-pointer
+// Os: -mframe-pointer=none
// Os: -Os
// RUN: %clang_cl /Ot --target=i686-pc-windows-msvc -### -- %s 2>&1 | FileCheck -check-prefix=Ot %s
// RUN: %clang_cl /Ot --target=x86_64-pc-windows-msvc -### -- %s 2>&1 | FileCheck -check-prefix=Ot %s
-// Ot-NOT: -mdisable-fp-elim
-// Ot-NOT: -momit-leaf-frame-pointer
+// Ot: -mframe-pointer=none
// Ot: -O2
// RUN: %clang_cl /Ox --target=i686-pc-windows-msvc -### -- %s 2>&1 | FileCheck -check-prefix=Ox %s
// RUN: %clang_cl /Ox --target=x86_64-pc-windows-msvc -### -- %s 2>&1 | FileCheck -check-prefix=Ox %s
-// Ox-NOT: -mdisable-fp-elim
-// Ox-NOT: -momit-leaf-frame-pointer
+// Ox: -mframe-pointer=none
// Ox: -O2
// RUN: %clang_cl --target=i686-pc-win32 /O2sy- -### -- %s 2>&1 | FileCheck -check-prefix=PR24003 %s
-// PR24003: -mdisable-fp-elim
-// PR24003-NOT: -momit-leaf-frame-pointer
+// PR24003: -mframe-pointer=all
// PR24003: -Os
// RUN: %clang_cl --target=i686-pc-win32 -Werror /Oy- /O2 -### -- %s 2>&1 | FileCheck -check-prefix=Oy_2 %s
-// Oy_2-NOT: -momit-leaf-frame-pointer
+// Oy_2: -mframe-pointer=all
// Oy_2: -O2
// RUN: %clang_cl --target=aarch64-pc-windows-msvc -Werror /Oy- /O2 -### -- %s 2>&1 | FileCheck -check-prefix=Oy_aarch64 %s
-// Oy_aarch64: -mdisable-fp-elim
+// Oy_aarch64: -mframe-pointer=all
// Oy_aarch64: -O2
// RUN: %clang_cl --target=i686-pc-win32 -Werror /O2 /O2 -### -- %s 2>&1 | FileCheck -check-prefix=O2O2 %s
// RUN: %clang_cl /Zs -Werror /Oy -- %s 2>&1
// RUN: %clang_cl --target=i686-pc-win32 -Werror /Oy- -### -- %s 2>&1 | FileCheck -check-prefix=Oy_ %s
-// Oy_: -mdisable-fp-elim
+// Oy_: -mframe-pointer=all
// RUN: %clang_cl /Qvec -### -- %s 2>&1 | FileCheck -check-prefix=Qvec %s
// Qvec: -vectorize-loops
// I386: "-S"
// I386: "-disable-free"
// I386: "-mrelocation-model" "static"
-// I386: "-mdisable-fp-elim"
+// I386: "-mframe-pointer=all"
// I386: "-masm-verbose"
// I386: "-munwind-tables"
// I386: "-Os"
-// KEEP-ALL: "-mdisable-fp-elim"
-// KEEP-ALL-NOT: "-momit-leaf-frame-pointer"
-
-// KEEP-NON-LEAF: "-mdisable-fp-elim"
-// KEEP-NON-LEAF: "-momit-leaf-frame-pointer"
-
-// KEEP-NONE-NOT: "-mdisable-fp-elim"
-// KEEP-NONE-NOT: "-momit-leaf-frame-pointer"
+// KEEP-ALL: "-mframe-pointer=all"
+// KEEP-NON-LEAF: "-mframe-pointer=non-leaf"
+// KEEP-NONE: "-mframe-pointer=none"
// On Linux x86, omit frame pointer when optimization is enabled.
// RUN: %clang -### -target i386-linux -S -fomit-frame-pointer %s 2>&1 | \
// RUN: %clang -### -target armv7s-apple-ios -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-7S %s
// WARN-OMIT-7S: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7s'
-// WARN-OMIT-7S: "-mdisable-fp-elim"
-// WARN-OMIT-7S-NOT: "-momit-leaf-frame-pointer"
+// WARN-OMIT-7S: "-mframe-pointer=all"
// RUN: %clang -### -target armv7k-apple-watchos -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-7K %s
// WARN-OMIT-7K: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7k'
-// WARN-OMIT-7K: "-mdisable-fp-elim"
-// WARN-OMIT-7K-NOT: "-momit-leaf-frame-pointer"
+// WARN-OMIT-7K: "-mframe-pointer=all"
// RUN: %clang -### -target armv7s-apple-ios8.0 -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-LEAF-7S %s
// WARN-OMIT-LEAF-7S-NOT: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
-// WARN-OMIT-LEAF-7S: "-mdisable-fp-elim"
-// WARN-OMIT-LEAF-7S: "-momit-leaf-frame-pointer"
+// WARN-OMIT-LEAF-7S: "-mframe-pointer=non-leaf"
// On the PS4, we default to omitting the frame pointer on leaf functions
// RUN: %clang -### -target x86_64-scei-ps4 -S %s 2>&1 | \
// RUN: %clang -target riscv64-unknown-linux-gnu -### -S -O3 %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK3-64 %s
// RUN: %clang -target riscv64-unknown-linux-gnu -### -S -Os %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECKs-64 %s
-// CHECK0-32: -mdisable-fp-elim
-// CHECK1-32-NOT: -mdisable-fp-elim
-// CHECK2-32-NOT: -mdisable-fp-elim
-// CHECK3-32-NOT: -mdisable-fp-elim
-// CHECKs-32-NOT: -mdisable-fp-elim
+// CHECK0-32: -mframe-pointer=all
+// CHECK1-32-NOT: -mframe-pointer=all
+// CHECK2-32-NOT: -mframe-pointer=all
+// CHECK3-32-NOT: -mframe-pointer=all
+// CHECKs-32-NOT: -mframe-pointer=all
-// CHECK0-64: -mdisable-fp-elim
-// CHECK1-64-NOT: -mdisable-fp-elim
-// CHECK2-64-NOT: -mdisable-fp-elim
-// CHECK3-64-NOT: -mdisable-fp-elim
-// CHECKs-64-NOT: -mdisable-fp-elim
-// CHECK-MACHO-64: -mdisable-fp-elim
+// CHECK0-64: -mframe-pointer=all
+// CHECK1-64-NOT: -mframe-pointer=all
+// CHECK2-64-NOT: -mframe-pointer=all
+// CHECK3-64-NOT: -mframe-pointer=all
+// CHECKs-64-NOT: -mframe-pointer=all
+// CHECK-MACHO-64: -mframe-pointer=all
// RUN: %clang -target armv7-windows-itanium -fno-omit-frame-pointer -### -S %s -O3 -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-NO-FPO
// RUN: %clang -target armv7-windows-itanium -fno-omit-frame-pointer -### -S %s -Os -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-NO-FPO
-// CHECK-DEFAULT: "-mdisable-fp-elim"
-// CHECK-FPO-NOT: "-mdisable-fp-elim"
-// CHECK-NO-FPO: "-mdisable-fp-elim"
+// CHECK-DEFAULT: "-mframe-pointer=all"
+// CHECK-FPO-NOT: "-mframe-pointer=all"
+// CHECK-NO-FPO: "-mframe-pointer=all"
// RUN: %clang -target xcore -x c++ %s -fexceptions -### -o %t.o 2>&1 | FileCheck -check-prefix CHECK-EXCEP %s
// RUN: %clang -target xcore %s -g0 -### -o %t.o 2>&1 | FileCheck -check-prefix CHECK-G0 %s
+// CHECK: "-mframe-pointer=none"
// CHECK: "-nostdsysteminc"
-// CHECK-NOT: "-mdisable-fp-elim"
-// CHECK-NOT: "-momit-leaf-frame-pointer"
// CHECK: "-fno-signed-char"
// CHECK: "-fno-use-cxa-atexit"
// CHECK-NOT: "-fcxx-exceptions"