]> granicus.if.org Git - clang/commitdiff
Driver: Stop forcing frame pointer usage on Windows
authorReid Kleckner <reid@kleckner.net>
Wed, 4 Feb 2015 23:45:07 +0000 (23:45 +0000)
committerReid Kleckner <reid@kleckner.net>
Wed, 4 Feb 2015 23:45:07 +0000 (23:45 +0000)
Previously, we would use a frame pointer by default on non-Linux OSs. On
Linux, any optimization flags imply -fomit-frame-pointer. XCore always
defaulted to -fomit-frame-pointer.

Now x86 Windows matches our behavior on Linux. All other ISAs supported
by Windows (ARM, x64) use xdata information, and frame pointers aren't
useful. Frame pointers are now off by default for such targets, but can
be forced via -fno-omit-frame-pointer and code using alloca().

In fact, on Win64 our frame-pointer prologue is not describable with
UNWIND_INFO. This change is a workaround to avoid using the broken FP
using prologue for most functions. This is PR22467.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228236 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Driver/Tools.cpp

index 24363ba9977f7cba09968ffa70401650cfad8812..c45955441c4ec373709b69e1199958527dce4898 100644 (file)
@@ -2288,27 +2288,49 @@ static bool addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
   return !StaticRuntimes.empty();
 }
 
+static bool areOptimizationsEnabled(const ArgList &Args) {
+  // Find the last -O arg and see if it is non-zero.
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
+    return !A->getOption().matches(options::OPT_O0);
+  // Defaults to -O0.
+  return false;
+}
+
 static bool shouldUseFramePointerForTarget(const ArgList &Args,
                                            const llvm::Triple &Triple) {
-  switch (Triple.getArch()) {
-  // Don't use a frame pointer on linux if optimizing for certain targets.
-  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:
-    if (Triple.isOSLinux())
-      if (Arg *A = Args.getLastArg(options::OPT_O_Group))
-        if (!A->getOption().matches(options::OPT_O0))
-          return false;
-    return true;
-  case llvm::Triple::xcore:
+  // XCore never wants frame pointers, regardless of OS.
+  if (Triple.getArch() == llvm::Triple::xcore) {
     return false;
-  default:
-    return true;
   }
+
+  if (Triple.isOSLinux()) {
+    switch (Triple.getArch()) {
+    // Don't use a frame pointer on linux if optimizing for certain targets.
+    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);
+    default:
+      // All other supported Windows ISAs use xdata unwind information, so frame
+      // pointers are not generally useful.
+      return false;
+    }
+  }
+
+  return true;
 }
 
 static bool shouldUseFramePointer(const ArgList &Args,