From 736d3e1f8be649c3abacf37bc9b3ba41ac387c42 Mon Sep 17 00:00:00 2001 From: dim Date: Fri, 1 Mar 2013 17:37:57 +0000 Subject: [PATCH] MFC r247166: Pull in r172354 from upstream clang trunk: Refactor the x86 CPU name logic in the driver and pass -march and -mcpu flag information down from the Clang driver into the Gold linker plugin for LTO. This allows specifying -march on the linker commandline and should hopefully have it pass all the way through to the LTO optimizer. Fixes PR14697. Pull in r175919 from upstream clang trunk: Driver: Pass down the -march setting down to -cc1as on x86 too. The assembler historically didn't make use of any target features, but this has changed when support for old CPUs that don't support long nops was added. This should fix the long nops that still occurred in crt*.o, and possibly other object files, if the system was compiled for a CPU that does not support those, such as Geode. Note that gcc on i386 also does not pass through any -march, -mcpu or -mtune setting to gas, but this has not caused any trouble yet, because gas defaults to i386. Reported by: lev git-svn-id: svn://svn.freebsd.org/base/stable/9@247557 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- contrib/llvm/tools/clang/lib/Driver/Tools.cpp | 146 ++++++++++-------- contrib/llvm/tools/clang/lib/Driver/Tools.h | 1 + 2 files changed, 86 insertions(+), 61 deletions(-) diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp index c3bcb9193..473473d75 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Tools.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Tools.cpp @@ -1114,10 +1114,59 @@ void Clang::AddSparcTargetArgs(const ArgList &Args, } } +static const char *getX86TargetCPU(const ArgList &Args, + const llvm::Triple &Triple) { + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { + if (StringRef(A->getValue()) != "native") + return A->getValue(); + + // FIXME: Reject attempts to use -march=native unless the target matches + // the host. + // + // FIXME: We should also incorporate the detected target features for use + // with -native. + std::string CPU = llvm::sys::getHostCPUName(); + if (!CPU.empty() && CPU != "generic") + return Args.MakeArgString(CPU); + } + + // Select the default CPU if none was given (or detection failed). + + if (Triple.getArch() != llvm::Triple::x86_64 && + Triple.getArch() != llvm::Triple::x86) + return 0; // This routine is only handling x86 targets. + + bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64; + + // FIXME: Need target hooks. + if (Triple.isOSDarwin()) + return Is64Bit ? "core2" : "yonah"; + + // Everything else goes to x86-64 in 64-bit mode. + if (Is64Bit) + return "x86-64"; + + if (Triple.getOSName().startswith("haiku")) + return "i586"; + if (Triple.getOSName().startswith("openbsd")) + return "i486"; + if (Triple.getOSName().startswith("bitrig")) + return "i686"; + if (Triple.getOSName().startswith("freebsd")) + return "i486"; + if (Triple.getOSName().startswith("netbsd")) + return "i486"; + // All x86 devices running Android have core2 as their common + // denominator. This makes a better choice than pentium4. + if (Triple.getEnvironment() == llvm::Triple::Android) + return "core2"; + + // Fallback to p4. + return "pentium4"; +} + void Clang::AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - const bool isAndroid = - getToolChain().getTriple().getEnvironment() == llvm::Triple::Android; if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) || @@ -1130,65 +1179,7 @@ void Clang::AddX86TargetArgs(const ArgList &Args, false)) CmdArgs.push_back("-no-implicit-float"); - const char *CPUName = 0; - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { - if (StringRef(A->getValue()) == "native") { - // FIXME: Reject attempts to use -march=native unless the target matches - // the host. - // - // FIXME: We should also incorporate the detected target features for use - // with -native. - std::string CPU = llvm::sys::getHostCPUName(); - if (!CPU.empty() && CPU != "generic") - CPUName = Args.MakeArgString(CPU); - } else - CPUName = A->getValue(); - } - - // Select the default CPU if none was given (or detection failed). - if (!CPUName) { - // FIXME: Need target hooks. - if (getToolChain().getTriple().isOSDarwin()) { - if (getToolChain().getArch() == llvm::Triple::x86_64) - CPUName = "core2"; - else if (getToolChain().getArch() == llvm::Triple::x86) - CPUName = "yonah"; - } else if (getToolChain().getOS().startswith("haiku")) { - if (getToolChain().getArch() == llvm::Triple::x86_64) - CPUName = "x86-64"; - else if (getToolChain().getArch() == llvm::Triple::x86) - CPUName = "i586"; - } else if (getToolChain().getOS().startswith("openbsd")) { - if (getToolChain().getArch() == llvm::Triple::x86_64) - CPUName = "x86-64"; - else if (getToolChain().getArch() == llvm::Triple::x86) - CPUName = "i486"; - } else if (getToolChain().getOS().startswith("bitrig")) { - if (getToolChain().getArch() == llvm::Triple::x86_64) - CPUName = "x86-64"; - else if (getToolChain().getArch() == llvm::Triple::x86) - CPUName = "i686"; - } else if (getToolChain().getOS().startswith("freebsd")) { - if (getToolChain().getArch() == llvm::Triple::x86_64) - CPUName = "x86-64"; - else if (getToolChain().getArch() == llvm::Triple::x86) - CPUName = "i486"; - } else if (getToolChain().getOS().startswith("netbsd")) { - if (getToolChain().getArch() == llvm::Triple::x86_64) - CPUName = "x86-64"; - else if (getToolChain().getArch() == llvm::Triple::x86) - CPUName = "i486"; - } else { - if (getToolChain().getArch() == llvm::Triple::x86_64) - CPUName = "x86-64"; - else if (getToolChain().getArch() == llvm::Triple::x86) - // All x86 devices running Android have core2 as their common - // denominator. This makes a better choice than pentium4. - CPUName = isAndroid ? "core2" : "pentium4"; - } - } - - if (CPUName) { + if (const char *CPUName = getX86TargetCPU(Args, getToolChain().getTriple())) { CmdArgs.push_back("-target-cpu"); CmdArgs.push_back(CPUName); } @@ -3091,6 +3082,15 @@ void ClangAs::AddARMTargetArgs(const ArgList &Args, addFPMathArgs(D, A, Args, CmdArgs, getARMTargetCPU(Args, Triple)); } +void ClangAs::AddX86TargetArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + // Set the CPU based on -march=. + if (const char *CPUName = getX86TargetCPU(Args, getToolChain().getTriple())) { + CmdArgs.push_back("-target-cpu"); + CmdArgs.push_back(CPUName); + } +} + /// Add options related to the Objective-C runtime/ABI. /// /// Returns true if the runtime is non-fragile. @@ -3261,6 +3261,11 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, case llvm::Triple::thumb: AddARMTargetArgs(Args, CmdArgs); break; + + case llvm::Triple::x86: + case llvm::Triple::x86_64: + AddX86TargetArgs(Args, CmdArgs); + break; } // Ignore explicit -force_cpusubtype_ALL option. @@ -6068,8 +6073,27 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-plugin"); std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so"; CmdArgs.push_back(Args.MakeArgString(Plugin)); + + // Try to pass driver level flags relevant to LTO code generation down to + // the plugin. + + // Handle architecture-specific flags for selecting CPU variants. + if (ToolChain.getArch() == llvm::Triple::x86 || + ToolChain.getArch() == llvm::Triple::x86_64) + CmdArgs.push_back( + Args.MakeArgString(Twine("-plugin-opt=mcpu=") + + getX86TargetCPU(Args, ToolChain.getTriple()))); + else if (ToolChain.getArch() == llvm::Triple::arm || + ToolChain.getArch() == llvm::Triple::thumb) + CmdArgs.push_back( + Args.MakeArgString(Twine("-plugin-opt=mcpu=") + + getARMTargetCPU(Args, ToolChain.getTriple()))); + + // FIXME: Factor out logic for MIPS, PPC, and other targets to support this + // as well. } + if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) CmdArgs.push_back("--no-demangle"); diff --git a/contrib/llvm/tools/clang/lib/Driver/Tools.h b/contrib/llvm/tools/clang/lib/Driver/Tools.h index 5898c660a..7ac43ec9b 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Tools.h +++ b/contrib/llvm/tools/clang/lib/Driver/Tools.h @@ -68,6 +68,7 @@ namespace tools { /// \brief Clang integrated assembler tool. class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool { void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; + void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; public: ClangAs(const ToolChain &TC) : Tool("clang::as", "clang integrated assembler", TC) {} -- 2.45.0