10b57cec5SDimitry Andric //===-- X86Subtarget.cpp - X86 Subtarget Information ----------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the X86 specific subclass of TargetSubtargetInfo. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 135ffd83dbSDimitry Andric #include "X86Subtarget.h" 145ffd83dbSDimitry Andric #include "MCTargetDesc/X86BaseInfo.h" 150b57cec5SDimitry Andric #include "X86.h" 160b57cec5SDimitry Andric #include "X86CallLowering.h" 170b57cec5SDimitry Andric #include "X86LegalizerInfo.h" 180b57cec5SDimitry Andric #include "X86MacroFusion.h" 190b57cec5SDimitry Andric #include "X86RegisterBankInfo.h" 200b57cec5SDimitry Andric #include "X86TargetMachine.h" 210b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 240b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 250b57cec5SDimitry Andric #include "llvm/IR/ConstantRange.h" 260b57cec5SDimitry Andric #include "llvm/IR/Function.h" 270b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 280b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 290b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 300b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 310b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 320b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 330b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 340b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric #if defined(_MSC_VER) 370b57cec5SDimitry Andric #include <intrin.h> 380b57cec5SDimitry Andric #endif 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric using namespace llvm; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric #define DEBUG_TYPE "subtarget" 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric #define GET_SUBTARGETINFO_TARGET_DESC 450b57cec5SDimitry Andric #define GET_SUBTARGETINFO_CTOR 460b57cec5SDimitry Andric #include "X86GenSubtargetInfo.inc" 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric // Temporary option to control early if-conversion for x86 while adding machine 490b57cec5SDimitry Andric // models. 500b57cec5SDimitry Andric static cl::opt<bool> 510b57cec5SDimitry Andric X86EarlyIfConv("x86-early-ifcvt", cl::Hidden, 520b57cec5SDimitry Andric cl::desc("Enable early if-conversion on X86")); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric /// Classify a blockaddress reference for the current subtarget according to how 560b57cec5SDimitry Andric /// we should reference it in a non-pcrel context. 570b57cec5SDimitry Andric unsigned char X86Subtarget::classifyBlockAddressReference() const { 580b57cec5SDimitry Andric return classifyLocalReference(nullptr); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric /// Classify a global variable reference for the current subtarget according to 620b57cec5SDimitry Andric /// how we should reference it in a non-pcrel context. 630b57cec5SDimitry Andric unsigned char 640b57cec5SDimitry Andric X86Subtarget::classifyGlobalReference(const GlobalValue *GV) const { 650b57cec5SDimitry Andric return classifyGlobalReference(GV, *GV->getParent()); 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric unsigned char 690b57cec5SDimitry Andric X86Subtarget::classifyLocalReference(const GlobalValue *GV) const { 700b57cec5SDimitry Andric // If we're not PIC, it's not very interesting. 710b57cec5SDimitry Andric if (!isPositionIndependent()) 720b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric if (is64Bit()) { 750b57cec5SDimitry Andric // 64-bit ELF PIC local references may use GOTOFF relocations. 760b57cec5SDimitry Andric if (isTargetELF()) { 770b57cec5SDimitry Andric switch (TM.getCodeModel()) { 780b57cec5SDimitry Andric // 64-bit small code model is simple: All rip-relative. 790b57cec5SDimitry Andric case CodeModel::Tiny: 800b57cec5SDimitry Andric llvm_unreachable("Tiny codesize model not supported on X86"); 810b57cec5SDimitry Andric case CodeModel::Small: 820b57cec5SDimitry Andric case CodeModel::Kernel: 830b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric // The large PIC code model uses GOTOFF. 860b57cec5SDimitry Andric case CodeModel::Large: 870b57cec5SDimitry Andric return X86II::MO_GOTOFF; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // Medium is a hybrid: RIP-rel for code, GOTOFF for DSO local data. 900b57cec5SDimitry Andric case CodeModel::Medium: 915ffd83dbSDimitry Andric // Constant pool and jump table handling pass a nullptr to this 925ffd83dbSDimitry Andric // function so we need to use isa_and_nonnull. 935ffd83dbSDimitry Andric if (isa_and_nonnull<Function>(GV)) 940b57cec5SDimitry Andric return X86II::MO_NO_FLAG; // All code is RIP-relative 950b57cec5SDimitry Andric return X86II::MO_GOTOFF; // Local symbols use GOTOFF. 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric llvm_unreachable("invalid code model"); 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // Otherwise, this is either a RIP-relative reference or a 64-bit movabsq, 1010b57cec5SDimitry Andric // both of which use MO_NO_FLAG. 1020b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric // The COFF dynamic linker just patches the executable sections. 1060b57cec5SDimitry Andric if (isTargetCOFF()) 1070b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric if (isTargetDarwin()) { 1100b57cec5SDimitry Andric // 32 bit macho has no relocation for a-b if a is undefined, even if 1110b57cec5SDimitry Andric // b is in the section that is being relocated. 1120b57cec5SDimitry Andric // This means we have to use o load even for GVs that are known to be 1130b57cec5SDimitry Andric // local to the dso. 1140b57cec5SDimitry Andric if (GV && (GV->isDeclarationForLinker() || GV->hasCommonLinkage())) 1150b57cec5SDimitry Andric return X86II::MO_DARWIN_NONLAZY_PIC_BASE; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric return X86II::MO_PIC_BASE_OFFSET; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric return X86II::MO_GOTOFF; 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV, 1240b57cec5SDimitry Andric const Module &M) const { 1250b57cec5SDimitry Andric // The static large model never uses stubs. 1260b57cec5SDimitry Andric if (TM.getCodeModel() == CodeModel::Large && !isPositionIndependent()) 1270b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // Absolute symbols can be referenced directly. 1300b57cec5SDimitry Andric if (GV) { 1310b57cec5SDimitry Andric if (Optional<ConstantRange> CR = GV->getAbsoluteSymbolRange()) { 1320b57cec5SDimitry Andric // See if we can use the 8-bit immediate form. Note that some instructions 1330b57cec5SDimitry Andric // will sign extend the immediate operand, so to be conservative we only 1340b57cec5SDimitry Andric // accept the range [0,128). 1350b57cec5SDimitry Andric if (CR->getUnsignedMax().ult(128)) 1360b57cec5SDimitry Andric return X86II::MO_ABS8; 1370b57cec5SDimitry Andric else 1380b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric if (TM.shouldAssumeDSOLocal(M, GV)) 1430b57cec5SDimitry Andric return classifyLocalReference(GV); 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric if (isTargetCOFF()) { 1460b57cec5SDimitry Andric if (GV->hasDLLImportStorageClass()) 1470b57cec5SDimitry Andric return X86II::MO_DLLIMPORT; 1480b57cec5SDimitry Andric return X86II::MO_COFFSTUB; 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric // Some JIT users use *-win32-elf triples; these shouldn't use GOT tables. 1510b57cec5SDimitry Andric if (isOSWindows()) 1520b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric if (is64Bit()) { 1550b57cec5SDimitry Andric // ELF supports a large, truly PIC code model with non-PC relative GOT 1560b57cec5SDimitry Andric // references. Other object file formats do not. Use the no-flag, 64-bit 1570b57cec5SDimitry Andric // reference for them. 1580b57cec5SDimitry Andric if (TM.getCodeModel() == CodeModel::Large) 1590b57cec5SDimitry Andric return isTargetELF() ? X86II::MO_GOT : X86II::MO_NO_FLAG; 1600b57cec5SDimitry Andric return X86II::MO_GOTPCREL; 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric if (isTargetDarwin()) { 1640b57cec5SDimitry Andric if (!isPositionIndependent()) 1650b57cec5SDimitry Andric return X86II::MO_DARWIN_NONLAZY; 1660b57cec5SDimitry Andric return X86II::MO_DARWIN_NONLAZY_PIC_BASE; 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 169*e8d8bef9SDimitry Andric // 32-bit ELF references GlobalAddress directly in static relocation model. 170*e8d8bef9SDimitry Andric // We cannot use MO_GOT because EBX may not be set up. 171*e8d8bef9SDimitry Andric if (TM.getRelocationModel() == Reloc::Static) 172*e8d8bef9SDimitry Andric return X86II::MO_NO_FLAG; 1730b57cec5SDimitry Andric return X86II::MO_GOT; 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric unsigned char 1770b57cec5SDimitry Andric X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV) const { 1780b57cec5SDimitry Andric return classifyGlobalFunctionReference(GV, *GV->getParent()); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric unsigned char 1820b57cec5SDimitry Andric X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV, 1830b57cec5SDimitry Andric const Module &M) const { 1840b57cec5SDimitry Andric if (TM.shouldAssumeDSOLocal(M, GV)) 1850b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric // Functions on COFF can be non-DSO local for two reasons: 1880b57cec5SDimitry Andric // - They are marked dllimport 1890b57cec5SDimitry Andric // - They are extern_weak, and a stub is needed 1900b57cec5SDimitry Andric if (isTargetCOFF()) { 1910b57cec5SDimitry Andric if (GV->hasDLLImportStorageClass()) 1920b57cec5SDimitry Andric return X86II::MO_DLLIMPORT; 1930b57cec5SDimitry Andric return X86II::MO_COFFSTUB; 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric const Function *F = dyn_cast_or_null<Function>(GV); 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric if (isTargetELF()) { 1990b57cec5SDimitry Andric if (is64Bit() && F && (CallingConv::X86_RegCall == F->getCallingConv())) 2000b57cec5SDimitry Andric // According to psABI, PLT stub clobbers XMM8-XMM15. 2010b57cec5SDimitry Andric // In Regcall calling convention those registers are used for passing 2020b57cec5SDimitry Andric // parameters. Thus we need to prevent lazy binding in Regcall. 2030b57cec5SDimitry Andric return X86II::MO_GOTPCREL; 2040b57cec5SDimitry Andric // If PLT must be avoided then the call should be via GOTPCREL. 2050b57cec5SDimitry Andric if (((F && F->hasFnAttribute(Attribute::NonLazyBind)) || 2060b57cec5SDimitry Andric (!F && M.getRtLibUseGOT())) && 2070b57cec5SDimitry Andric is64Bit()) 2080b57cec5SDimitry Andric return X86II::MO_GOTPCREL; 209*e8d8bef9SDimitry Andric // Reference ExternalSymbol directly in static relocation model. 210*e8d8bef9SDimitry Andric if (!is64Bit() && !GV && TM.getRelocationModel() == Reloc::Static) 211*e8d8bef9SDimitry Andric return X86II::MO_NO_FLAG; 2120b57cec5SDimitry Andric return X86II::MO_PLT; 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric if (is64Bit()) { 2160b57cec5SDimitry Andric if (F && F->hasFnAttribute(Attribute::NonLazyBind)) 2170b57cec5SDimitry Andric // If the function is marked as non-lazy, generate an indirect call 2180b57cec5SDimitry Andric // which loads from the GOT directly. This avoids runtime overhead 2190b57cec5SDimitry Andric // at the cost of eager binding (and one extra byte of encoding). 2200b57cec5SDimitry Andric return X86II::MO_GOTPCREL; 2210b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric return X86II::MO_NO_FLAG; 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric /// Return true if the subtarget allows calls to immediate address. 2280b57cec5SDimitry Andric bool X86Subtarget::isLegalToCallImmediateAddr() const { 2290b57cec5SDimitry Andric // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32 2300b57cec5SDimitry Andric // but WinCOFFObjectWriter::RecordRelocation cannot emit them. Once it does, 2310b57cec5SDimitry Andric // the following check for Win32 should be removed. 2320b57cec5SDimitry Andric if (In64BitMode || isTargetWin32()) 2330b57cec5SDimitry Andric return false; 2340b57cec5SDimitry Andric return isTargetELF() || TM.getRelocationModel() == Reloc::Static; 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 237*e8d8bef9SDimitry Andric void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, 238*e8d8bef9SDimitry Andric StringRef FS) { 239*e8d8bef9SDimitry Andric if (CPU.empty()) 240*e8d8bef9SDimitry Andric CPU = "generic"; 2410b57cec5SDimitry Andric 242*e8d8bef9SDimitry Andric if (TuneCPU.empty()) 243*e8d8bef9SDimitry Andric TuneCPU = "i586"; // FIXME: "generic" is more modern than llc tests expect. 2440b57cec5SDimitry Andric 245*e8d8bef9SDimitry Andric std::string FullFS = X86_MC::ParseX86Triple(TargetTriple); 246*e8d8bef9SDimitry Andric assert(!FullFS.empty() && "Failed to parse X86 triple"); 2470b57cec5SDimitry Andric 248*e8d8bef9SDimitry Andric if (!FS.empty()) 249*e8d8bef9SDimitry Andric FullFS = (Twine(FullFS) + "," + FS).str(); 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric // Parse features string and set the CPU. 252*e8d8bef9SDimitry Andric ParseSubtargetFeatures(CPU, TuneCPU, FullFS); 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric // All CPUs that implement SSE4.2 or SSE4A support unaligned accesses of 2550b57cec5SDimitry Andric // 16-bytes and under that are reasonably fast. These features were 2560b57cec5SDimitry Andric // introduced with Intel's Nehalem/Silvermont and AMD's Family10h 2570b57cec5SDimitry Andric // micro-architectures respectively. 2580b57cec5SDimitry Andric if (hasSSE42() || hasSSE4A()) 2590b57cec5SDimitry Andric IsUAMem16Slow = false; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel 2620b57cec5SDimitry Andric << ", 3DNowLevel " << X863DNowLevel << ", 64bit " 2630b57cec5SDimitry Andric << HasX86_64 << "\n"); 2640b57cec5SDimitry Andric if (In64BitMode && !HasX86_64) 2650b57cec5SDimitry Andric report_fatal_error("64-bit code requested on a subtarget that doesn't " 2660b57cec5SDimitry Andric "support it!"); 2670b57cec5SDimitry Andric 268*e8d8bef9SDimitry Andric // Stack alignment is 16 bytes on Darwin, Linux, kFreeBSD and for all 269*e8d8bef9SDimitry Andric // 64-bit targets. On Solaris (32-bit), stack alignment is 4 bytes 270*e8d8bef9SDimitry Andric // following the i386 psABI, while on Illumos it is always 16 bytes. 2710b57cec5SDimitry Andric if (StackAlignOverride) 2728bcb0991SDimitry Andric stackAlignment = *StackAlignOverride; 273*e8d8bef9SDimitry Andric else if (isTargetDarwin() || isTargetLinux() || isTargetKFreeBSD() || 274*e8d8bef9SDimitry Andric In64BitMode) 2758bcb0991SDimitry Andric stackAlignment = Align(16); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric // Consume the vector width attribute or apply any target specific limit. 2780b57cec5SDimitry Andric if (PreferVectorWidthOverride) 2790b57cec5SDimitry Andric PreferVectorWidth = PreferVectorWidthOverride; 2808bcb0991SDimitry Andric else if (Prefer128Bit) 2818bcb0991SDimitry Andric PreferVectorWidth = 128; 2820b57cec5SDimitry Andric else if (Prefer256Bit) 2830b57cec5SDimitry Andric PreferVectorWidth = 256; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU, 287*e8d8bef9SDimitry Andric StringRef TuneCPU, 2880b57cec5SDimitry Andric StringRef FS) { 289*e8d8bef9SDimitry Andric initSubtargetFeatures(CPU, TuneCPU, FS); 2900b57cec5SDimitry Andric return *this; 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 293*e8d8bef9SDimitry Andric X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, 294*e8d8bef9SDimitry Andric StringRef FS, const X86TargetMachine &TM, 2958bcb0991SDimitry Andric MaybeAlign StackAlignOverride, 2960b57cec5SDimitry Andric unsigned PreferVectorWidthOverride, 2970b57cec5SDimitry Andric unsigned RequiredVectorWidth) 298*e8d8bef9SDimitry Andric : X86GenSubtargetInfo(TT, CPU, TuneCPU, FS), 299*e8d8bef9SDimitry Andric PICStyle(PICStyles::Style::None), TM(TM), TargetTriple(TT), 300*e8d8bef9SDimitry Andric StackAlignOverride(StackAlignOverride), 3010b57cec5SDimitry Andric PreferVectorWidthOverride(PreferVectorWidthOverride), 3020b57cec5SDimitry Andric RequiredVectorWidth(RequiredVectorWidth), 303*e8d8bef9SDimitry Andric InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)), 304*e8d8bef9SDimitry Andric TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) { 3050b57cec5SDimitry Andric // Determine the PICStyle based on the target selected. 3060b57cec5SDimitry Andric if (!isPositionIndependent()) 307480093f4SDimitry Andric setPICStyle(PICStyles::Style::None); 3080b57cec5SDimitry Andric else if (is64Bit()) 309480093f4SDimitry Andric setPICStyle(PICStyles::Style::RIPRel); 3100b57cec5SDimitry Andric else if (isTargetCOFF()) 311480093f4SDimitry Andric setPICStyle(PICStyles::Style::None); 3120b57cec5SDimitry Andric else if (isTargetDarwin()) 313480093f4SDimitry Andric setPICStyle(PICStyles::Style::StubPIC); 3140b57cec5SDimitry Andric else if (isTargetELF()) 315480093f4SDimitry Andric setPICStyle(PICStyles::Style::GOT); 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric CallLoweringInfo.reset(new X86CallLowering(*getTargetLowering())); 3180b57cec5SDimitry Andric Legalizer.reset(new X86LegalizerInfo(*this, TM)); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric auto *RBI = new X86RegisterBankInfo(*getRegisterInfo()); 3210b57cec5SDimitry Andric RegBankInfo.reset(RBI); 3220b57cec5SDimitry Andric InstSelector.reset(createX86InstructionSelector(TM, *this, *RBI)); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric const CallLowering *X86Subtarget::getCallLowering() const { 3260b57cec5SDimitry Andric return CallLoweringInfo.get(); 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric 3298bcb0991SDimitry Andric InstructionSelector *X86Subtarget::getInstructionSelector() const { 3300b57cec5SDimitry Andric return InstSelector.get(); 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric const LegalizerInfo *X86Subtarget::getLegalizerInfo() const { 3340b57cec5SDimitry Andric return Legalizer.get(); 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric const RegisterBankInfo *X86Subtarget::getRegBankInfo() const { 3380b57cec5SDimitry Andric return RegBankInfo.get(); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric bool X86Subtarget::enableEarlyIfConversion() const { 3420b57cec5SDimitry Andric return hasCMov() && X86EarlyIfConv; 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric void X86Subtarget::getPostRAMutations( 3460b57cec5SDimitry Andric std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { 3470b57cec5SDimitry Andric Mutations.push_back(createX86MacroFusionDAGMutation()); 3480b57cec5SDimitry Andric } 3495ffd83dbSDimitry Andric 3505ffd83dbSDimitry Andric bool X86Subtarget::isPositionIndependent() const { 3515ffd83dbSDimitry Andric return TM.isPositionIndependent(); 3525ffd83dbSDimitry Andric } 353