tabloid.adroit created this revision.
tabloid.adroit added reviewers: chandlerc, rnk, t.p.northover.
Herald added a subscriber: cfe-commits.

set cc1 '-mframe-pointer=' according to driver options 
m(no-)omit-leaf-frame-pointer
and f(no-)omit-frame-pointer

This makes -fomit-frame-pointer imply -momit-leaf-frame-pointer.
This matches GCC's behavior. PR9825

following up
https://reviews.llvm.org/D56351

related:
https://reviews.llvm.org/D55915


Repository:
  rC Clang

https://reviews.llvm.org/D56353

Files:
  include/clang/Basic/CodeGenOptions.def
  include/clang/Basic/CodeGenOptions.h
  include/clang/Driver/CC1Options.td
  include/clang/Driver/Options.td
  lib/CodeGen/CGCall.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/x86_64-profiling-keep-fp.c
  test/CodeGenCXX/global-init.cpp
  test/CodeGenObjCXX/msabi-stret.mm
  test/Driver/cl-options.c
  test/Driver/clang-translation.c
  test/Driver/frame-pointer-elim.c
  test/Driver/frame-pointer.c
  test/Driver/woa-fp.c
  test/Driver/xcore-opts.c

Index: test/Driver/xcore-opts.c
===================================================================
--- test/Driver/xcore-opts.c
+++ test/Driver/xcore-opts.c
@@ -3,9 +3,8 @@
 // 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: "-momit-leaf-frame-pointer"
-// CHECK-NOT: "-mdisable-fp-elim"
 // CHECK: "-fno-signed-char"
 // CHECK: "-fno-use-cxa-atexit"
 // CHECK-NOT: "-fcxx-exceptions"
Index: test/Driver/woa-fp.c
===================================================================
--- test/Driver/woa-fp.c
+++ test/Driver/woa-fp.c
@@ -34,7 +34,7 @@
 // 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"
 
Index: test/Driver/frame-pointer.c
===================================================================
--- test/Driver/frame-pointer.c
+++ test/Driver/frame-pointer.c
@@ -57,15 +57,15 @@
 // 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
Index: test/Driver/frame-pointer-elim.c
===================================================================
--- test/Driver/frame-pointer-elim.c
+++ test/Driver/frame-pointer-elim.c
@@ -2,65 +2,62 @@
 // pointer, for unoptimized we should have a leaf frame pointer.
 // RUN: %clang -### -target i386-pc-linux-gnu -S -O1 %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=LINUX-OPT %s
-// LINUX-OPT: "-momit-leaf-frame-pointer"
+// LINUX-OPT: "-mframe-pointer=none"
 
 // RUN: %clang -### -target i386-pc-linux-gnu -S %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=LINUX %s
-// LINUX-NOT: "-momit-leaf-frame-pointer"
+// LINUX: "-mframe-pointer=all"
 
 // CloudABI follows the same rules as Linux.
 // RUN: %clang -### -target x86_64-unknown-cloudabi -S -O1 %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=CLOUDABI-OPT %s
-// CLOUDABI-OPT: "-momit-leaf-frame-pointer"
+// CLOUDABI-OPT: "-mframe-pointer=none"
 
 // RUN: %clang -### -target x86_64-unknown-cloudabi -S %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=CLOUDABI %s
-// CLOUDABI-NOT: "-momit-leaf-frame-pointer"
+// CLOUDABI: "-mframe-pointer=all"
 
 // NetBSD follows the same rules as Linux.
 // RUN: %clang -### -target x86_64-unknown-netbsd -S -O1 %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=NETBSD-OPT %s
-// NETBSD-OPT: "-momit-leaf-frame-pointer"
+// NETBSD-OPT: "-mframe-pointer=none"
 
 // RUN: %clang -### -target x86_64-unknown-netbsd -S %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=NETBSD %s
-// NETBSD-NOT: "-momit-leaf-frame-pointer"
+// NETBSD: "-mframe-pointer=all"
 
 // Darwin disables omitting the leaf frame pointer even under optimization
 // unless the command lines are given.
 // RUN: %clang -### -target i386-apple-darwin -S %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=DARWIN %s
-// DARWIN: "-mdisable-fp-elim"
+// DARWIN: "-mframe-pointer=all"
 
 // RUN: %clang -### -target i386-apple-darwin -S -O1 %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=DARWIN-OPT %s
-// DARWIN-OPT-NOT: "-momit-leaf-frame-pointer"
+// DARWIN-OPT: "-mframe-pointer=all"
 
 // RUN: %clang -### -target i386-darwin -S -fomit-frame-pointer %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=OMIT_ALL %s
-// OMIT_ALL-NOT: "-mdisable-fp-elim"
+// OMIT_ALL: "-mframe-pointer=none"
 
 // RUN: %clang -### -target i386-darwin -S -momit-leaf-frame-pointer %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=OMIT_LEAF %s
-// OMIT_LEAF: "-momit-leaf-frame-pointer"
+// OMIT_LEAF: "-mframe-pointer=non-leaf"
 
 // 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
 // (OMIT_LEAF check line is above)
Index: test/Driver/clang-translation.c
===================================================================
--- test/Driver/clang-translation.c
+++ test/Driver/clang-translation.c
@@ -3,7 +3,7 @@
 // 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"
Index: test/Driver/cl-options.c
===================================================================
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -153,29 +153,25 @@
 
 // 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: -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: -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: -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: -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: -momit-leaf-frame-pointer
+// Oy_2: -mframe-pointer=all
 // Oy_2: -O2
 
 // RUN: %clang_cl --target=i686-pc-win32 -Werror /O2 /O2 -### -- %s 2>&1 | FileCheck -check-prefix=O2O2 %s
@@ -184,7 +180,7 @@
 // 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
Index: test/CodeGenObjCXX/msabi-stret.mm
===================================================================
--- test/CodeGenObjCXX/msabi-stret.mm
+++ test/CodeGenObjCXX/msabi-stret.mm
@@ -1,4 +1,4 @@
-// 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;
Index: test/CodeGenCXX/global-init.cpp
===================================================================
--- test/CodeGenCXX/global-init.cpp
+++ test/CodeGenCXX/global-init.cpp
@@ -1,7 +1,6 @@
 // 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 {
@@ -208,4 +207,4 @@
 
 // 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"{{.*}} }
Index: test/CodeGen/x86_64-profiling-keep-fp.c
===================================================================
--- test/CodeGen/x86_64-profiling-keep-fp.c
+++ test/CodeGen/x86_64-profiling-keep-fp.c
@@ -1,7 +1,9 @@
 // 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
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -811,8 +811,27 @@
   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)) {
+    StringRef Name = A->getValue();
+    unsigned FP = llvm::StringSwitch<unsigned>(Name)
+        .Case("all", CodeGenOptions::FP_All)
+        .Case("non-leaf", CodeGenOptions::FP_NonLeaf)
+        .Case("none", CodeGenOptions::FP_None)
+        .Default(~0U);
+    if (FP == ~0U) {
+      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+      Success = false;
+    } else
+      Opts.setFramePointer(
+          static_cast<CodeGenOptions::FramePointerKind>(FP));
+  }
+
+  // -pg may override -mframe-pointer
+  if (Args.hasArg(OPT_pg))
+    Opts.setFramePointer(CodeGenOptions::FP_All);
+
   Opts.DisableFree = Args.hasArg(OPT_disable_free);
   Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names);
   Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls);
@@ -859,7 +878,6 @@
   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);
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -571,32 +571,52 @@
   return true;
 }
 
-static bool shouldUseFramePointer(const ArgList &Args,
-                                  const llvm::Triple &Triple) {
-  if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
-                               options::OPT_fomit_frame_pointer))
-    return A->getOption().matches(options::OPT_fno_omit_frame_pointer) ||
-           mustUseNonLeafFramePointerForTarget(Triple);
-
-  if (Args.hasArg(options::OPT_pg))
-    return true;
-
-  return useFramePointerForTargetByDefault(Args, Triple);
-}
+static StringRef DetermineFramePointer(const ArgList &Args,
+                                       const llvm::Triple &Triple) {
+  Arg *FP = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
+                            options::OPT_fomit_frame_pointer);
+  Arg *LeafFP = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
+                                options::OPT_momit_leaf_frame_pointer);
 
-static bool shouldUseLeafFramePointer(const ArgList &Args,
-                                      const llvm::Triple &Triple) {
-  if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
-                               options::OPT_momit_leaf_frame_pointer))
-    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
+  // Target-dependent frame pointer requirement
 
-  if (Args.hasArg(options::OPT_pg))
-    return true;
+  if (mustUseNonLeafFramePointerForTarget(Triple)) {
+    if (LeafFP &&
+        LeafFP->getOption().matches(options::OPT_momit_leaf_frame_pointer))
+      return "non-leaf";
+    return "all";
+  }
 
   if (Triple.isPS4CPU())
-    return false;
+    return "non-leaf";
+
+  // Target-independent frame pointer requirement
 
-  return useFramePointerForTargetByDefault(Args, Triple);
+  if (!FP && !LeafFP) {
+    if (Args.hasArg(options::OPT_pg))
+      return "all";
+
+    return useFramePointerForTargetByDefault(Args, Triple) ? "all" : "none";
+  }
+
+  if (FP && !LeafFP)
+    return FP->getOption().matches(options::OPT_fno_omit_frame_pointer) ?
+            "all" : "none";
+
+  if (!FP && LeafFP)
+    return
+      LeafFP->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer) ?
+        "all" : "non-leaf";
+
+  assert (FP && LeafFP);
+
+  if (FP->getOption().matches(options::OPT_fomit_frame_pointer))
+    return "none";
+
+  if (LeafFP->getOption().matches(options::OPT_momit_leaf_frame_pointer))
+    return "non-leaf";
+
+  return "all";
 }
 
 /// Add a CC1 option to specify the debug compilation directory.
@@ -3869,8 +3889,9 @@
   if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
     CmdArgs.push_back("-fdefault-calling-conv=stdcall");
 
-  if (shouldUseFramePointer(Args, RawTriple))
-    CmdArgs.push_back("-mdisable-fp-elim");
+  CmdArgs.push_back(Args.MakeArgString("-mframe-pointer=" +
+                    DetermineFramePointer(Args, RawTriple)));
+
   if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
                     options::OPT_fno_zero_initialized_in_bss))
     CmdArgs.push_back("-mno-zero-initialized-in-bss");
@@ -4041,9 +4062,6 @@
     CmdArgs.push_back(A->getValue());
   }
 
-  if (!shouldUseLeafFramePointer(Args, RawTriple))
-    CmdArgs.push_back("-momit-leaf-frame-pointer");
-
   // Explicitly error on some things we know we don't support and can't just
   // ignore.
   if (!Args.hasArg(options::OPT_fallow_unsupported)) {
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1728,16 +1728,14 @@
     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");
-    }
+    if (CodeGenOpts.getFramePointer() == CodeGenOptions::FP_All)
+      FuncAttrs.addAttribute("frame-pointer", "all");
+    else if (CodeGenOpts.getFramePointer() == CodeGenOptions::FP_NonLeaf)
+      FuncAttrs.addAttribute("frame-pointer", "non-leaf");
+    else if (CodeGenOpts.getFramePointer() == CodeGenOptions::FP_None)
+      FuncAttrs.addAttribute("frame-pointer", "none");
+    else
+      llvm_unreachable("unknown frame-pointer");
 
     FuncAttrs.addAttribute("less-precise-fpmad",
                            llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -2236,7 +2236,7 @@
 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>;
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -266,8 +266,8 @@
   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 effect of frame pointer elimination optimization (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">,
Index: include/clang/Basic/CodeGenOptions.h
===================================================================
--- include/clang/Basic/CodeGenOptions.h
+++ include/clang/Basic/CodeGenOptions.h
@@ -118,6 +118,12 @@
 
   enum SignReturnAddressKeyValue { AKey, BKey };
 
+  enum FramePointerKind {
+    FP_All,         // Keep all frame pointers.
+    FP_NonLeaf,     // Keep non-leaf frame pointers.
+    FP_None,        // Omit all frame pointers.
+  };
+
   /// The code model to use (-mcmodel).
   std::string CodeModel;
 
Index: include/clang/Basic/CodeGenOptions.def
===================================================================
--- include/clang/Basic/CodeGenOptions.def
+++ include/clang/Basic/CodeGenOptions.def
@@ -48,7 +48,8 @@
                                      ///< 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, FP_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.
@@ -151,8 +152,6 @@
 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.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to