diff options
Diffstat (limited to 'clang/lib/Driver')
-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); |