From be6ed962cfe0cc61250a514e2c98feb4e08d45ad Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Tue, 20 Aug 2019 07:21:14 +0000 Subject: [PATCH] Revert r365860 for PR42966 (with a tweak to the test case for r365862) > Author: maskray > Date: Thu Jul 11 19:01:51 2019 > New Revision: 365860 > > URL: http://llvm.org/viewvc/llvm-project?rev=365860&view=rev > Log: > [Driver] Refactor interaction between -f(no-)?omit-frame-pointer and -m(no-)?omit-leaf-frame-pointer > > Use a tri-state enum to represent shouldUseFramePointer() and > shouldUseLeafFramePointer(). > > This simplifies the logic and fixes PR9825: > -fno-omit-frame-pointer doesn't imply -mno-omit-leaf-frame-pointer. > > and PR24003: > /Oy- /O2 should not omit leaf frame pointer: this matches MSVC x86-32. > (/Oy- is a no-op on MSVC x86-64.) > > and: > when CC1 option -mdisable-fp-elim if absent, -momit-leaf-frame-pointer > can also be omitted. > > The new behavior matches GCC: > -fomit-frame-pointer wins over -mno-omit-leaf-frame-pointer > -fno-omit-frame-pointer loses out to -momit-leaf-frame-pointer > > The behavior makes lots of sense. 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 with -f(no-)?omit-frame-pointer and > -m(no-)?omit-leaf-pointer. > > Reviewed By: ychen > > Differential Revision: https://reviews.llvm.org/D64294 git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_90@369333 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/ToolChains/Clang.cpp | 58 ++++++++++++---------- test/Driver/cl-options.c | 10 ++-- test/Driver/clang_f_opts.c | 5 ++ test/Driver/frame-pointer-elim.c | 84 ++++++++++++-------------------- test/Driver/xcore-opts.c | 2 +- 5 files changed, 72 insertions(+), 87 deletions(-) diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index cb861f27ae..2508178423 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -501,8 +501,6 @@ static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) { return codegenoptions::LimitedDebugInfo; } -enum class FramePointerKind { None, NonLeaf, All }; - static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { switch (Triple.getArch()){ default: @@ -517,9 +515,6 @@ static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { static bool useFramePointerForTargetByDefault(const ArgList &Args, const llvm::Triple &Triple) { - if (Args.hasArg(options::OPT_pg)) - return true; - switch (Triple.getArch()) { case llvm::Triple::xcore: case llvm::Triple::wasm32: @@ -579,22 +574,32 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args, return true; } -static 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); - bool NoOmitFP = - A && A->getOption().matches(options::OPT_fno_omit_frame_pointer); - if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) || - (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) { - 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 FramePointerKind::None; +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 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); + + if (Args.hasArg(options::OPT_pg)) + return true; + + if (Triple.isPS4CPU()) + return false; + + return useFramePointerForTargetByDefault(Args, Triple); } /// Add a CC1 option to specify the debug compilation directory. @@ -3946,12 +3951,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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) { + if (shouldUseFramePointer(Args, RawTriple)) CmdArgs.push_back("-mdisable-fp-elim"); - if (FPKeepKind == FramePointerKind::NonLeaf) - CmdArgs.push_back("-momit-leaf-frame-pointer"); - } if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, options::OPT_fno_zero_initialized_in_bss)) CmdArgs.push_back("-mno-zero-initialized-in-bss"); @@ -4136,6 +4137,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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)) { @@ -5489,7 +5493,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } if (Arg *A = Args.getLastArg(options::OPT_pg)) - if (FPKeepKind == FramePointerKind::None) + if (!shouldUseFramePointer(Args, Triple)) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer" << A->getAsString(Args); diff --git a/test/Driver/cl-options.c b/test/Driver/cl-options.c index 51a98e5350..04aa08a557 100644 --- a/test/Driver/cl-options.c +++ b/test/Driver/cl-options.c @@ -161,28 +161,28 @@ // 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: -momit-leaf-frame-pointer // 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: -momit-leaf-frame-pointer // 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: -momit-leaf-frame-pointer // 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: -momit-leaf-frame-pointer // 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: -momit-leaf-frame-pointer // Oy_2: -O2 // RUN: %clang_cl --target=aarch64-pc-windows-msvc -Werror /Oy- /O2 -### -- %s 2>&1 | FileCheck -check-prefix=Oy_aarch64 %s diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c index 17feaab26a..d3d80fdec4 100644 --- a/test/Driver/clang_f_opts.c +++ b/test/Driver/clang_f_opts.c @@ -548,6 +548,11 @@ // CHECK-NO-NULL-POINTER-CHECKS: "-fno-delete-null-pointer-checks" // CHECK-NULL-POINTER-CHECKS-NOT: "-fno-delete-null-pointer-checks" +// RUN: %clang -### -S -fomit-frame-pointer -pg %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-OMIT-FP-PG %s +// RUN: %clang -### -S -fomit-frame-pointer -fno-omit-frame-pointer -pg %s 2>&1 | FileCheck -check-prefix=CHECK-MIX-NO-OMIT-FP-PG %s +// CHECK-NO-MIX-OMIT-FP-PG: '-fomit-frame-pointer' not allowed with '-pg' +// CHECK-MIX-NO-OMIT-FP-PG-NOT: '-fomit-frame-pointer' not allowed with '-pg' + // RUN: %clang -### -S -target x86_64-unknown-linux -frecord-gcc-switches %s 2>&1 | FileCheck -check-prefix=CHECK-RECORD-GCC-SWITCHES %s // RUN: %clang -### -S -target x86_64-unknown-linux -fno-record-gcc-switches %s 2>&1 | FileCheck -check-prefix=CHECK-NO-RECORD-GCC-SWITCHES %s // RUN: %clang -### -S -target x86_64-unknown-linux -fno-record-gcc-switches -frecord-gcc-switches %s 2>&1 | FileCheck -check-prefix=CHECK-RECORD-GCC-SWITCHES %s diff --git a/test/Driver/frame-pointer-elim.c b/test/Driver/frame-pointer-elim.c index f035860bf0..300953f2e8 100644 --- a/test/Driver/frame-pointer-elim.c +++ b/test/Driver/frame-pointer-elim.c @@ -1,74 +1,48 @@ -// KEEP-ALL: "-mdisable-fp-elim" -// KEEP-ALL-NOT: "-momit-leaf-frame-pointer" +// For these next two tests when optimized we should omit the leaf frame +// 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" -// 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" - -// On Linux x86, omit frame pointer when optimization is enabled. -// RUN: %clang -### -target i386-linux -S -fomit-frame-pointer %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target i386-linux -S -O1 %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s - -// -fno-omit-frame-pointer or -pg disables frame pointer omission. -// RUN: %clang -### -target i386-linux -S %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target i386-linux -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-ALL %s -// RUN: %clang -### -target i386-linux -S -O1 -pg %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-ALL %s - -// -momit-leaf-frame-pointer omits leaf frame pointer. -// -fno-omit-frame-pointer loses out to -momit-leaf-frame-pointer. -// RUN: %clang -### -target i386 -S -momit-leaf-frame-pointer %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s -// RUN: %clang -### -target i386-linux -S -O1 -momit-leaf-frame-pointer %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s - -// Explicit or default -fomit-frame-pointer wins over -mno-omit-leaf-frame-pointer. -// RUN: %clang -### -target i386 -S %s -fomit-frame-pointer -mno-omit-leaf-frame-pointer 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s -// RUN: %clang -### -target i386-linux -S %s -O1 -mno-omit-leaf-frame-pointer 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s - -// -pg -fomit-frame-pointer => error. -// RUN: %clang -### -S -fomit-frame-pointer -pg %s 2>&1 | FileCheck -check-prefix=CHECK-NO-MIX-OMIT-FP-PG %s -// RUN: %clang -### -S -fomit-frame-pointer -fno-omit-frame-pointer -pg %s 2>&1 | FileCheck -check-prefix=CHECK-MIX-NO-OMIT-FP-PG %s -// CHECK-NO-MIX-OMIT-FP-PG: '-fomit-frame-pointer' not allowed with '-pg' -// CHECK-MIX-NO-OMIT-FP-PG-NOT: '-fomit-frame-pointer' not allowed with '-pg' +// RUN: %clang -### -target i386-pc-linux-gnu -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=LINUX %s +// LINUX-NOT: "-momit-leaf-frame-pointer" // CloudABI follows the same rules as Linux. // RUN: %clang -### -target x86_64-unknown-cloudabi -S -O1 %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: FileCheck --check-prefix=CLOUDABI-OPT %s +// CLOUDABI-OPT: "-momit-leaf-frame-pointer" // RUN: %clang -### -target x86_64-unknown-cloudabi -S %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: FileCheck --check-prefix=CLOUDABI %s +// CLOUDABI-NOT: "-momit-leaf-frame-pointer" // NetBSD follows the same rules as Linux. // RUN: %clang -### -target x86_64-unknown-netbsd -S -O1 %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: FileCheck --check-prefix=NETBSD-OPT %s +// NETBSD-OPT: "-momit-leaf-frame-pointer" // RUN: %clang -### -target x86_64-unknown-netbsd -S %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: FileCheck --check-prefix=NETBSD %s +// NETBSD-NOT: "-momit-leaf-frame-pointer" // 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=KEEP-ALL %s +// RUN: FileCheck --check-prefix=DARWIN %s +// DARWIN: "-mdisable-fp-elim" // RUN: %clang -### -target i386-apple-darwin -S -O1 %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: FileCheck --check-prefix=DARWIN-OPT %s +// DARWIN-OPT-NOT: "-momit-leaf-frame-pointer" // RUN: %clang -### -target i386-darwin -S -fomit-frame-pointer %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: FileCheck --check-prefix=OMIT_ALL %s +// OMIT_ALL-NOT: "-mdisable-fp-elim" // RUN: %clang -### -target i386-darwin -S -momit-leaf-frame-pointer %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: FileCheck --check-prefix=OMIT_LEAF %s +// OMIT_LEAF: "-momit-leaf-frame-pointer" // RUN: %clang -### -target armv7s-apple-ios -fomit-frame-pointer %s 2>&1 | \ // RUN: FileCheck --check-prefix=WARN-OMIT-7S %s @@ -89,15 +63,17 @@ // WARN-OMIT-LEAF-7S: "-momit-leaf-frame-pointer" // On the PS4, we default to omitting the frame pointer on leaf functions +// (OMIT_LEAF check line is above) // RUN: %clang -### -target x86_64-scei-ps4 -S %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: FileCheck --check-prefix=OMIT_LEAF %s // RUN: %clang -### -target x86_64-scei-ps4 -S -O2 %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: FileCheck --check-prefix=OMIT_LEAF %s // RUN: %clang -### -target powerpc64 -S %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: FileCheck --check-prefix=KEEP_ALL %s +// KEEP_ALL: "-mdisable-fp-elim" // RUN: %clang -### -target powerpc64 -S -O1 %s 2>&1 | \ -// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: FileCheck --check-prefix=OMIT_ALL %s void f0() {} void f1() { f0(); } diff --git a/test/Driver/xcore-opts.c b/test/Driver/xcore-opts.c index abbc88e103..9300085724 100644 --- a/test/Driver/xcore-opts.c +++ b/test/Driver/xcore-opts.c @@ -4,8 +4,8 @@ // RUN: %clang -target xcore %s -g0 -### -o %t.o 2>&1 | FileCheck -check-prefix CHECK-G0 %s // CHECK: "-nostdsysteminc" +// CHECK: "-momit-leaf-frame-pointer" // CHECK-NOT: "-mdisable-fp-elim" -// CHECK-NOT: "-momit-leaf-frame-pointer" // CHECK: "-fno-signed-char" // CHECK: "-fno-use-cxa-atexit" // CHECK-NOT: "-fcxx-exceptions" -- 2.40.0