clang  7.0.0svn
X86.cpp
Go to the documentation of this file.
1 //===--- X86.cpp - X86 Helpers for Tools ------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "X86.h"
11 #include "ToolChains/CommonArgs.h"
12 #include "clang/Driver/Driver.h"
14 #include "clang/Driver/Options.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/Option/ArgList.h"
17 
18 using namespace clang::driver;
19 using namespace clang::driver::tools;
20 using namespace clang;
21 using namespace llvm::opt;
22 
23 const char *x86::getX86TargetCPU(const ArgList &Args,
24  const llvm::Triple &Triple) {
25  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
26  if (StringRef(A->getValue()) != "native") {
27  if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
28  return "core-avx2";
29 
30  return A->getValue();
31  }
32 
33  // FIXME: Reject attempts to use -march=native unless the target matches
34  // the host.
35  //
36  // FIXME: We should also incorporate the detected target features for use
37  // with -native.
38  std::string CPU = llvm::sys::getHostCPUName();
39  if (!CPU.empty() && CPU != "generic")
40  return Args.MakeArgString(CPU);
41  }
42 
43  if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) {
44  // Mapping built by looking at lib/Basic's X86TargetInfo::initFeatureMap().
45  StringRef Arch = A->getValue();
46  const char *CPU = nullptr;
47  if (Triple.getArch() == llvm::Triple::x86) { // 32-bit-only /arch: flags.
48  CPU = llvm::StringSwitch<const char *>(Arch)
49  .Case("IA32", "i386")
50  .Case("SSE", "pentium3")
51  .Case("SSE2", "pentium4")
52  .Default(nullptr);
53  }
54  if (CPU == nullptr) { // 32-bit and 64-bit /arch: flags.
55  CPU = llvm::StringSwitch<const char *>(Arch)
56  .Case("AVX", "sandybridge")
57  .Case("AVX2", "haswell")
58  .Case("AVX512F", "knl")
59  .Case("AVX512", "skylake-avx512")
60  .Default(nullptr);
61  }
62  if (CPU) {
63  A->claim();
64  return CPU;
65  }
66  }
67 
68  // Select the default CPU if none was given (or detection failed).
69 
70  if (Triple.getArch() != llvm::Triple::x86_64 &&
71  Triple.getArch() != llvm::Triple::x86)
72  return nullptr; // This routine is only handling x86 targets.
73 
74  bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
75 
76  // FIXME: Need target hooks.
77  if (Triple.isOSDarwin()) {
78  if (Triple.getArchName() == "x86_64h")
79  return "core-avx2";
80  // macosx10.12 drops support for all pre-Penryn Macs.
81  // Simulators can still run on 10.11 though, like Xcode.
82  if (Triple.isMacOSX() && !Triple.isOSVersionLT(10, 12))
83  return "penryn";
84  // The oldest x86_64 Macs have core2/Merom; the oldest x86 Macs have Yonah.
85  return Is64Bit ? "core2" : "yonah";
86  }
87 
88  // Set up default CPU name for PS4 compilers.
89  if (Triple.isPS4CPU())
90  return "btver2";
91 
92  // On Android use targets compatible with gcc
93  if (Triple.isAndroid())
94  return Is64Bit ? "x86-64" : "i686";
95 
96  // Everything else goes to x86-64 in 64-bit mode.
97  if (Is64Bit)
98  return "x86-64";
99 
100  switch (Triple.getOS()) {
101  case llvm::Triple::FreeBSD:
102  case llvm::Triple::NetBSD:
103  case llvm::Triple::OpenBSD:
104  return "i486";
105  case llvm::Triple::Haiku:
106  return "i586";
107  default:
108  // Fallback to p4.
109  return "pentium4";
110  }
111 }
112 
113 void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
114  const ArgList &Args,
115  std::vector<StringRef> &Features) {
116  // If -march=native, autodetect the feature list.
117  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
118  if (StringRef(A->getValue()) == "native") {
119  llvm::StringMap<bool> HostFeatures;
120  if (llvm::sys::getHostCPUFeatures(HostFeatures))
121  for (auto &F : HostFeatures)
122  Features.push_back(
123  Args.MakeArgString((F.second ? "+" : "-") + F.first()));
124  }
125  }
126 
127  if (Triple.getArchName() == "x86_64h") {
128  // x86_64h implies quite a few of the more modern subtarget features
129  // for Haswell class CPUs, but not all of them. Opt-out of a few.
130  Features.push_back("-rdrnd");
131  Features.push_back("-aes");
132  Features.push_back("-pclmul");
133  Features.push_back("-rtm");
134  Features.push_back("-fsgsbase");
135  }
136 
137  const llvm::Triple::ArchType ArchType = Triple.getArch();
138  // Add features to be compatible with gcc for Android.
139  if (Triple.isAndroid()) {
140  if (ArchType == llvm::Triple::x86_64) {
141  Features.push_back("+sse4.2");
142  Features.push_back("+popcnt");
143  } else
144  Features.push_back("+ssse3");
145  }
146 
147  // Now add any that the user explicitly requested on the command line,
148  // which may override the defaults.
149  handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
150 }
void handleTargetFeaturesGroup(const llvm::opt::ArgList &Args, std::vector< StringRef > &Features, llvm::opt::OptSpecifier Group)
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:59
const char * getX86TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Dataflow Directional Tag Classes.
void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features)