forked from OSchip/llvm-project
[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 llvm-svn: 365860
This commit is contained in:
parent
9577086628
commit
dc0396614f
|
@ -501,6 +501,8 @@ 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:
|
||||
|
@ -515,6 +517,9 @@ 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:
|
||||
|
@ -574,32 +579,22 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args,
|
|||
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 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);
|
||||
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;
|
||||
}
|
||||
|
||||
/// Add a CC1 option to specify the debug compilation directory.
|
||||
|
@ -3960,8 +3955,12 @@ 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");
|
||||
|
||||
if (shouldUseFramePointer(Args, RawTriple))
|
||||
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");
|
||||
}
|
||||
if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
|
||||
options::OPT_fno_zero_initialized_in_bss))
|
||||
CmdArgs.push_back("-mno-zero-initialized-in-bss");
|
||||
|
@ -4146,9 +4145,6 @@ 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)) {
|
||||
|
@ -5503,7 +5499,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
}
|
||||
|
||||
if (Arg *A = Args.getLastArg(options::OPT_pg))
|
||||
if (!shouldUseFramePointer(Args, Triple))
|
||||
if (FPKeepKind == FramePointerKind::None)
|
||||
D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer"
|
||||
<< A->getAsString(Args);
|
||||
|
||||
|
|
|
@ -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: -momit-leaf-frame-pointer
|
||||
// Os-NOT: -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: -momit-leaf-frame-pointer
|
||||
// Ot-NOT: -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: -momit-leaf-frame-pointer
|
||||
// Ox-NOT: -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: -momit-leaf-frame-pointer
|
||||
// PR24003-NOT: -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: -momit-leaf-frame-pointer
|
||||
// Oy_2-NOT: -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
|
||||
|
|
|
@ -548,11 +548,6 @@
|
|||
// 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
|
||||
|
|
|
@ -1,48 +1,74 @@
|
|||
// 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-ALL: "-mdisable-fp-elim"
|
||||
// KEEP-ALL-NOT: "-momit-leaf-frame-pointer"
|
||||
|
||||
// RUN: %clang -### -target i386-pc-linux-gnu -S %s 2>&1 | \
|
||||
// RUN: FileCheck --check-prefix=LINUX %s
|
||||
// LINUX-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"
|
||||
|
||||
// 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'
|
||||
|
||||
// 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"
|
||||
// RUN: FileCheck --check-prefix=KEEP-NONE %s
|
||||
|
||||
// RUN: %clang -### -target x86_64-unknown-cloudabi -S %s 2>&1 | \
|
||||
// RUN: FileCheck --check-prefix=CLOUDABI %s
|
||||
// CLOUDABI-NOT: "-momit-leaf-frame-pointer"
|
||||
// RUN: FileCheck --check-prefix=KEEP-ALL %s
|
||||
|
||||
// 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"
|
||||
// RUN: FileCheck --check-prefix=KEEP-NONE %s
|
||||
|
||||
// RUN: %clang -### -target x86_64-unknown-netbsd -S %s 2>&1 | \
|
||||
// RUN: FileCheck --check-prefix=NETBSD %s
|
||||
// NETBSD-NOT: "-momit-leaf-frame-pointer"
|
||||
// RUN: FileCheck --check-prefix=KEEP-ALL %s
|
||||
|
||||
// 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"
|
||||
// RUN: FileCheck --check-prefix=KEEP-ALL %s
|
||||
|
||||
// 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"
|
||||
// RUN: FileCheck --check-prefix=KEEP-ALL %s
|
||||
|
||||
// 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"
|
||||
// RUN: FileCheck --check-prefix=KEEP-NONE %s
|
||||
|
||||
// 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"
|
||||
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
|
||||
|
||||
// RUN: %clang -### -target armv7s-apple-ios -fomit-frame-pointer %s 2>&1 | \
|
||||
// RUN: FileCheck --check-prefix=WARN-OMIT-7S %s
|
||||
|
@ -63,11 +89,10 @@
|
|||
// 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=OMIT_LEAF %s
|
||||
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
|
||||
// RUN: %clang -### -target x86_64-scei-ps4 -S -O2 %s 2>&1 | \
|
||||
// RUN: FileCheck --check-prefix=OMIT_LEAF %s
|
||||
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
|
||||
|
||||
void f0() {}
|
||||
void f1() { f0(); }
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue