LLVM  4.0.0
X86TargetMachine.cpp
Go to the documentation of this file.
1 //===-- X86TargetMachine.cpp - Define TargetMachine for the X86 -----------===//
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 // This file defines the X86 specific subclass of TargetMachine.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "X86TargetMachine.h"
15 #include "X86.h"
16 #include "X86CallLowering.h"
17 #include "X86TargetObjectFile.h"
18 #include "X86TargetTransformInfo.h"
22 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/IR/Function.h"
30 using namespace llvm;
31 
32 static cl::opt<bool> EnableMachineCombinerPass("x86-machine-combiner",
33  cl::desc("Enable the machine combiner pass"),
34  cl::init(true), cl::Hidden);
35 
36 namespace llvm {
38 }
39 
40 extern "C" void LLVMInitializeX86Target() {
41  // Register the target.
44 
50 }
51 
52 static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
53  if (TT.isOSBinFormatMachO()) {
54  if (TT.getArch() == Triple::x86_64)
55  return make_unique<X86_64MachoTargetObjectFile>();
56  return make_unique<TargetLoweringObjectFileMachO>();
57  }
58 
59  if (TT.isOSFreeBSD())
60  return make_unique<X86FreeBSDTargetObjectFile>();
61  if (TT.isOSLinux() || TT.isOSNaCl())
62  return make_unique<X86LinuxNaClTargetObjectFile>();
63  if (TT.isOSFuchsia())
64  return make_unique<X86FuchsiaTargetObjectFile>();
65  if (TT.isOSBinFormatELF())
66  return make_unique<X86ELFTargetObjectFile>();
68  return make_unique<X86WindowsTargetObjectFile>();
69  if (TT.isOSBinFormatCOFF())
70  return make_unique<TargetLoweringObjectFileCOFF>();
71  llvm_unreachable("unknown subtarget type");
72 }
73 
74 static std::string computeDataLayout(const Triple &TT) {
75  // X86 is little endian
76  std::string Ret = "e";
77 
79  // X86 and x32 have 32 bit pointers.
80  if ((TT.isArch64Bit() &&
81  (TT.getEnvironment() == Triple::GNUX32 || TT.isOSNaCl())) ||
82  !TT.isArch64Bit())
83  Ret += "-p:32:32";
84 
85  // Some ABIs align 64 bit integers and doubles to 64 bits, others to 32.
86  if (TT.isArch64Bit() || TT.isOSWindows() || TT.isOSNaCl())
87  Ret += "-i64:64";
88  else if (TT.isOSIAMCU())
89  Ret += "-i64:32-f64:32";
90  else
91  Ret += "-f64:32:64";
92 
93  // Some ABIs align long double to 128 bits, others to 32.
94  if (TT.isOSNaCl() || TT.isOSIAMCU())
95  ; // No f80
96  else if (TT.isArch64Bit() || TT.isOSDarwin())
97  Ret += "-f80:128";
98  else
99  Ret += "-f80:32";
100 
101  if (TT.isOSIAMCU())
102  Ret += "-f128:32";
103 
104  // The registers can hold 8, 16, 32 or, in x86-64, 64 bits.
105  if (TT.isArch64Bit())
106  Ret += "-n8:16:32:64";
107  else
108  Ret += "-n8:16:32";
109 
110  // The stack is aligned to 32 bits on some ABIs and 128 bits on others.
111  if ((!TT.isArch64Bit() && TT.isOSWindows()) || TT.isOSIAMCU())
112  Ret += "-a:0:32-S32";
113  else
114  Ret += "-S128";
115 
116  return Ret;
117 }
118 
121  bool is64Bit = TT.getArch() == Triple::x86_64;
122  if (!RM.hasValue()) {
123  // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode.
124  // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we
125  // use static relocation model by default.
126  if (TT.isOSDarwin()) {
127  if (is64Bit)
128  return Reloc::PIC_;
129  return Reloc::DynamicNoPIC;
130  }
131  if (TT.isOSWindows() && is64Bit)
132  return Reloc::PIC_;
133  return Reloc::Static;
134  }
135 
136  // ELF and X86-64 don't have a distinct DynamicNoPIC model. DynamicNoPIC
137  // is defined as a model for code which may be used in static or dynamic
138  // executables but not necessarily a shared library. On X86-32 we just
139  // compile in -static mode, in x86-64 we use PIC.
140  if (*RM == Reloc::DynamicNoPIC) {
141  if (is64Bit)
142  return Reloc::PIC_;
143  if (!TT.isOSDarwin())
144  return Reloc::Static;
145  }
146 
147  // If we are on Darwin, disallow static relocation model in X86-64 mode, since
148  // the Mach-O file format doesn't support it.
149  if (*RM == Reloc::Static && TT.isOSDarwin() && is64Bit)
150  return Reloc::PIC_;
151 
152  return *RM;
153 }
154 
155 /// Create an X86 target.
156 ///
158  StringRef CPU, StringRef FS,
159  const TargetOptions &Options,
162  : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
163  getEffectiveRelocModel(TT, RM), CM, OL),
164  TLOF(createTLOF(getTargetTriple())) {
165  // Windows stack unwinder gets confused when execution flow "falls through"
166  // after a call to 'noreturn' function.
167  // To prevent that, we emit a trap for 'unreachable' IR instructions.
168  // (which on X86, happens to be the 'ud2' instruction)
169  // On PS4, the "return address" of a 'noreturn' call must still be within
170  // the calling function, and TrapUnreachable is an easy way to get that.
171  // The check here for 64-bit windows is a bit icky, but as we're unlikely
172  // to ever want to mix 32 and 64-bit windows code in a single module
173  // this should be fine.
174  if ((TT.isOSWindows() && TT.getArch() == Triple::x86_64) || TT.isPS4())
175  this->Options.TrapUnreachable = true;
176 
177  initAsmInfo();
178 }
179 
181 
182 #ifdef LLVM_BUILD_GLOBAL_ISEL
183 namespace {
184 struct X86GISelActualAccessor : public GISelAccessor {
185  std::unique_ptr<CallLowering> CL;
186  X86GISelActualAccessor(CallLowering* CL): CL(CL) {}
187  const CallLowering *getCallLowering() const override {
188  return CL.get();
189  }
190  const InstructionSelector *getInstructionSelector() const override {
191  //TODO: Implement
192  return nullptr;
193  }
194  const LegalizerInfo *getLegalizerInfo() const override {
195  //TODO: Implement
196  return nullptr;
197  }
198  const RegisterBankInfo *getRegBankInfo() const override {
199  //TODO: Implement
200  return nullptr;
201  }
202 };
203 } // End anonymous namespace.
204 #endif
205 const X86Subtarget *
207  Attribute CPUAttr = F.getFnAttribute("target-cpu");
208  Attribute FSAttr = F.getFnAttribute("target-features");
209 
210  StringRef CPU = !CPUAttr.hasAttribute(Attribute::None)
211  ? CPUAttr.getValueAsString()
212  : (StringRef)TargetCPU;
214  ? FSAttr.getValueAsString()
215  : (StringRef)TargetFS;
216 
217  SmallString<512> Key;
218  Key.reserve(CPU.size() + FS.size());
219  Key += CPU;
220  Key += FS;
221 
222  // FIXME: This is related to the code below to reset the target options,
223  // we need to know whether or not the soft float flag is set on the
224  // function before we can generate a subtarget. We also need to use
225  // it as a key for the subtarget since that can be the only difference
226  // between two functions.
227  bool SoftFloat =
228  F.getFnAttribute("use-soft-float").getValueAsString() == "true";
229  // If the soft float attribute is set on the function turn on the soft float
230  // subtarget feature.
231  if (SoftFloat)
232  Key += FS.empty() ? "+soft-float" : ",+soft-float";
233 
234  FS = Key.substr(CPU.size());
235 
236  auto &I = SubtargetMap[Key];
237  if (!I) {
238  // This needs to be done before we create a new subtarget since any
239  // creation will depend on the TM and the code generation flags on the
240  // function that reside in TargetOptions.
242  I = llvm::make_unique<X86Subtarget>(TargetTriple, CPU, FS, *this,
244 #ifndef LLVM_BUILD_GLOBAL_ISEL
245  GISelAccessor *GISel = new GISelAccessor();
246 #else
247  X86GISelActualAccessor *GISel = new X86GISelActualAccessor(
248  new X86CallLowering(*I->getTargetLowering()));
249 #endif
250  I->setGISelAccessor(*GISel);
251  }
252  return I.get();
253 }
254 
255 //===----------------------------------------------------------------------===//
256 // Command line options for x86
257 //===----------------------------------------------------------------------===//
258 static cl::opt<bool>
259 UseVZeroUpper("x86-use-vzeroupper", cl::Hidden,
260  cl::desc("Minimize AVX to SSE transition penalty"),
261  cl::init(true));
262 
263 //===----------------------------------------------------------------------===//
264 // X86 TTI query.
265 //===----------------------------------------------------------------------===//
266 
268  return TargetIRAnalysis([this](const Function &F) {
269  return TargetTransformInfo(X86TTIImpl(this, F));
270  });
271 }
272 
273 
274 //===----------------------------------------------------------------------===//
275 // Pass Pipeline Configuration
276 //===----------------------------------------------------------------------===//
277 
278 namespace {
279 /// X86 Code Generator Pass Configuration Options.
280 class X86PassConfig : public TargetPassConfig {
281 public:
282  X86PassConfig(X86TargetMachine *TM, PassManagerBase &PM)
283  : TargetPassConfig(TM, PM) {}
284 
285  X86TargetMachine &getX86TargetMachine() const {
286  return getTM<X86TargetMachine>();
287  }
288 
290  createMachineScheduler(MachineSchedContext *C) const override {
293  return DAG;
294  }
295 
296  void addIRPasses() override;
297  bool addInstSelector() override;
298 #ifdef LLVM_BUILD_GLOBAL_ISEL
299  bool addIRTranslator() override;
300  bool addLegalizeMachineIR() override;
301  bool addRegBankSelect() override;
302  bool addGlobalInstructionSelect() override;
303 #endif
304 bool addILPOpts() override;
305  bool addPreISel() override;
306  void addPreRegAlloc() override;
307  void addPostRegAlloc() override;
308  void addPreEmitPass() override;
309  void addPreSched2() override;
310 };
311 } // namespace
312 
314  return new X86PassConfig(this, PM);
315 }
316 
317 void X86PassConfig::addIRPasses() {
318  addPass(createAtomicExpandPass(&getX86TargetMachine()));
319 
321 
322  if (TM->getOptLevel() != CodeGenOpt::None)
324 }
325 
326 bool X86PassConfig::addInstSelector() {
327  // Install an instruction selector.
328  addPass(createX86ISelDag(getX86TargetMachine(), getOptLevel()));
329 
330  // For ELF, cleanup any local-dynamic TLS accesses.
331  if (TM->getTargetTriple().isOSBinFormatELF() &&
332  getOptLevel() != CodeGenOpt::None)
334 
335  addPass(createX86GlobalBaseRegPass());
336  return false;
337 }
338 
339 #ifdef LLVM_BUILD_GLOBAL_ISEL
340 bool X86PassConfig::addIRTranslator() {
341  addPass(new IRTranslator());
342  return false;
343 }
344 
345 bool X86PassConfig::addLegalizeMachineIR() {
346  //TODO: Implement
347  return false;
348 }
349 
350 bool X86PassConfig::addRegBankSelect() {
351  //TODO: Implement
352  return false;
353 }
354 
355 bool X86PassConfig::addGlobalInstructionSelect() {
356  //TODO: Implement
357  return false;
358 }
359 #endif
360 
361 bool X86PassConfig::addILPOpts() {
362  addPass(&EarlyIfConverterID);
364  addPass(&MachineCombinerID);
365  return true;
366 }
367 
368 bool X86PassConfig::addPreISel() {
369  // Only add this pass for 32-bit x86 Windows.
370  const Triple &TT = TM->getTargetTriple();
371  if (TT.isOSWindows() && TT.getArch() == Triple::x86)
372  addPass(createX86WinEHStatePass());
373  return true;
374 }
375 
376 void X86PassConfig::addPreRegAlloc() {
377  if (getOptLevel() != CodeGenOpt::None) {
378  addPass(createX86FixupSetCC());
379  addPass(createX86OptimizeLEAs());
381  }
382 
383  addPass(createX86WinAllocaExpander());
384 }
385 
386 void X86PassConfig::addPostRegAlloc() {
388 }
389 
390 void X86PassConfig::addPreSched2() { addPass(createX86ExpandPseudoPass()); }
391 
392 void X86PassConfig::addPreEmitPass() {
393  if (getOptLevel() != CodeGenOpt::None)
394  addPass(createExecutionDependencyFixPass(&X86::VR128XRegClass));
395 
396  if (UseVZeroUpper)
397  addPass(createX86IssueVZeroUpperPass());
398 
399  if (getOptLevel() != CodeGenOpt::None) {
400  addPass(createX86FixupBWInsts());
401  addPass(createX86PadShortFunctions());
402  addPass(createX86FixupLEAs());
403  addPass(createX86EvexToVexInsts());
404  }
405 }
char & MachineCombinerID
This pass performs instruction combining using trace metrics to estimate critical-path and resource d...
The goal of this helper class is to gather the accessor to all the APIs related to GlobalISel...
Definition: GISelAccessor.h:29
static std::unique_ptr< TargetLoweringObjectFile > createTLOF(const Triple &TT)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void LLVMInitializeX86Target()
static cl::opt< bool > EnableMachineCombinerPass("x86-machine-combiner", cl::desc("Enable the machine combiner pass"), cl::init(true), cl::Hidden)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:575
FunctionPass * createX86OptimizeLEAs()
Return a pass that removes redundant LEA instructions and redundant address recalculations.
FunctionPass * createX86FixupBWInsts()
Return a Machine IR pass that selectively replaces certain byte and word instructions by equivalent 3...
bool hasValue() const
Definition: Optional.h:125
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
void initializeFixupBWInstPassPass(PassRegistry &)
Triple TargetTriple
Triple string, CPU name, and target feature strings the TargetMachine instance is created with...
FunctionPass * createX86FixupSetCC()
Return a pass that transforms setcc + movzx pairs into xor + setcc.
This file a TargetTransformInfo::Concept conforming object specific to the X86 target machine...
static std::string computeDataLayout(const Triple &TT)
TargetIRAnalysis getTargetIRAnalysis() override
Get a TargetIRAnalysis implementation for the target.
char & EarlyIfConverterID
EarlyIfConverter - This pass performs if-conversion on SSA form by inserting cmov instructions...
Analysis pass providing the TargetTransformInfo.
FunctionPass * createX86CallFrameOptimization()
Return a pass that optimizes the code-size of x86 call sequences.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:234
bool isOSIAMCU() const
Definition: Triple.h:485
FunctionPass * createX86IssueVZeroUpperPass()
This pass inserts AVX vzeroupper instructions before each call to avoid transition penalty between fu...
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
FunctionPass * createX86EvexToVexInsts()
This pass replaces EVEX ecnoded of AVX-512 instructiosn by VEX encoding when possible in order to red...
StringRef substr(size_t Start, size_t N=StringRef::npos) const
Return a reference to the substring from [Start, Start + N).
Definition: SmallString.h:246
void reserve(size_type N)
Definition: SmallVector.h:377
X86TargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Optional< Reloc::Model > RM, CodeModel::Model CM, CodeGenOpt::Level OL)
Create an X86 target.
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:185
static const char * getManglingComponent(const Triple &T)
Definition: DataLayout.cpp:155
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:540
ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules machine instructions while...
Holds all the information related to register banks.
void initializeGlobalISel(PassRegistry &Registry)
Initialize all passes linked into the GlobalISel library.
Definition: GlobalISel.cpp:21
FunctionPass * createX86PadShortFunctions()
Return a pass that pads short functions with NOOPs.
FunctionPass * createAtomicExpandPass(const TargetMachine *TM)
No attributes have been set.
Definition: Attributes.h:69
Target-Independent Code Generator Pass Configuration Options.
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1202
bool isOSLinux() const
Tests whether the OS is Linux.
Definition: Triple.h:550
#define F(x, y, z)
Definition: MD5.cpp:51
bool isOSNaCl() const
Tests whether the OS is NaCl (Native Client)
Definition: Triple.h:545
void initializeEvexToVexInstPassPass(PassRegistry &)
FunctionPass * createX86FixupLEAs()
Return a pass that selectively replaces certain instructions (like add, sub, inc, dec...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:270
ScheduleDAGMILive * createGenericSchedLive(MachineSchedContext *C)
Create the standard converging machine scheduler.
std::unique_ptr< ScheduleDAGMutation > createMacroFusionDAGMutation(const TargetInstrInfo *TII)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
FunctionPass * createInterleavedAccessPass(const TargetMachine *TM)
InterleavedAccess Pass - This pass identifies and matches interleaved memory accesses to target speci...
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
static Reloc::Model getEffectiveRelocModel(Optional< Reloc::Model > RM)
FunctionPass * createX86ExpandPseudoPass()
Return a Machine IR pass that expands X86-specific pseudo instructions into a sequence of actual inst...
FunctionPass * createX86GlobalBaseRegPass()
This pass initializes a global base register for PIC on x86-32.
static bool is64Bit(const char *name)
bool isOSFuchsia() const
Definition: Triple.h:471
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
This class describes a target machine that is implemented with the LLVM target-independent code gener...
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:570
bool isWindowsCoreCLREnvironment() const
Definition: Triple.h:512
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
Definition: Triple.h:455
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
FunctionPass * createExecutionDependencyFixPass(const TargetRegisterClass *RC)
createExecutionDependencyFixPass - This pass fixes execution time problems with dependent instruction...
unsigned StackAlignmentOverride
StackAlignmentOverride - Override default stack alignment for target.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
FunctionPass * createX86FloatingPointStackifierPass()
This function returns a pass which converts floating-point register references and pseudo instruction...
Target - Wrapper for Target specific information.
This file describes how to lower LLVM calls to machine code calls.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
static cl::opt< bool > UseVZeroUpper("x86-use-vzeroupper", cl::Hidden, cl::desc("Minimize AVX to SSE transition penalty"), cl::init(true))
FunctionPass * createX86WinAllocaExpander()
Return a pass that expands WinAlloca pseudo-instructions.
Provides the logic to select generic machine instructions.
ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of MachineInstrs. ...
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:565
FunctionPass * createX86ISelDag(X86TargetMachine &TM, CodeGenOpt::Level OptLevel)
This pass converts a legalized DAG into a X86-specific DAG, ready for instruction scheduling...
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
#define I(x, y, z)
Definition: MD5.cpp:54
void resetTargetOptions(const Function &F) const
Reset the target options based on the function's attributes.
Target & getTheX86_32Target()
const X86Subtarget * getSubtargetImpl(const Function &F) const override
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
const TargetInstrInfo * TII
Definition: ScheduleDAG.h:579
bool isOSFreeBSD() const
Definition: Triple.h:467
void initializeWinEHStatePassPass(PassRegistry &)
EnvironmentType getEnvironment() const
getEnvironment - Get the parsed environment type of this triple.
Definition: Triple.h:288
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:178
This file declares the IRTranslator pass.
RegisterTargetMachine - Helper template for registering a target machine implementation, for use in the target machine initialization function.
bool isKnownWindowsMSVCEnvironment() const
Checks if the environment is MSVC.
Definition: Triple.h:508
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:40
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
FunctionPass * createX86WinEHStatePass()
Return an IR pass that inserts EH registration stack objects and explicit EH state updates...
bool isPS4() const
Tests whether the target is the PS4 platform.
Definition: Triple.h:587
Target & getTheX86_64Target()
FunctionPass * createCleanupLocalDynamicTLSPass()
This pass combines multiple accesses to local-dynamic TLS variables so that the TLS base address for ...
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
Add a postprocessing step to the DAG builder.