diff options
author | Fangrui Song <maskray@google.com> | 2019-07-12 02:01:51 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-07-12 02:01:51 +0000 |
commit | dc0396614f84281ae662f98dbee4b6de4c3d79eb (patch) | |
tree | 1fa7b609835b217294cc55a950e3371e36a94282 /clang/lib/Driver/ToolChains/Clang.cpp | |
parent | 9577086628750230cfcb288b4a31a10e4880f0a7 (diff) | |
download | bcm5719-llvm-dc0396614f84281ae662f98dbee4b6de4c3d79eb.tar.gz bcm5719-llvm-dc0396614f84281ae662f98dbee4b6de4c3d79eb.zip |
[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
Diffstat (limited to 'clang/lib/Driver/ToolChains/Clang.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 6e2f1f302c2..bc548453859 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -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); |