X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86Subtarget.h;h=6934061c692253b56de8d422896f8829e7cafba1;hb=cf0db29df20d9c665da7e82bb261bdd7cf7f1b2b;hp=dde7e240b9d10ebebc9f4e9a2ca7cfd51772d6dc;hpb=2e2efd960056bbb7e4bbd843c8de55116d52aa7d;p=oota-llvm.git diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index dde7e240b9d..6934061c692 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -11,11 +11,15 @@ // //===----------------------------------------------------------------------===// -#ifndef X86SUBTARGET_H -#define X86SUBTARGET_H +#ifndef LLVM_LIB_TARGET_X86_X86SUBTARGET_H +#define LLVM_LIB_TARGET_X86_X86SUBTARGET_H -#include "llvm/CallingConv.h" +#include "X86FrameLowering.h" +#include "X86ISelLowering.h" +#include "X86InstrInfo.h" +#include "X86SelectionDAGInfo.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/CallingConv.h" #include "llvm/Target/TargetSubtargetInfo.h" #include @@ -27,7 +31,7 @@ class GlobalValue; class StringRef; class TargetMachine; -/// PICStyles - The X86 backend supports a number of different styles of PIC. +/// The X86 backend supports a number of different styles of PIC. /// namespace PICStyles { enum Style { @@ -39,10 +43,11 @@ enum Style { }; } -class X86Subtarget : public X86GenSubtargetInfo { +class X86Subtarget final : public X86GenSubtargetInfo { + protected: enum X86SSEEnum { - NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2 + NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F }; enum X863DNowEnum { @@ -50,100 +55,166 @@ protected: }; enum X86ProcFamilyEnum { - Others, IntelAtom + Others, IntelAtom, IntelSLM }; - /// X86ProcFamily - X86 processor family: Intel Atom, and others + /// X86 processor family: Intel Atom, and others X86ProcFamilyEnum X86ProcFamily; - /// PICStyle - Which PIC style to use - /// + /// Which PIC style to use PICStyles::Style PICStyle; - /// X86SSELevel - MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or - /// none supported. + /// MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, or none supported. X86SSEEnum X86SSELevel; - /// X863DNowLevel - 3DNow or 3DNow Athlon, or none supported. - /// + /// 3DNow, 3DNow Athlon, or none supported. X863DNowEnum X863DNowLevel; - /// HasCMov - True if this processor has conditional move instructions + /// True if this processor has conditional move instructions /// (generally pentium pro+). bool HasCMov; - /// HasX86_64 - True if the processor supports X86-64 instructions. - /// + /// True if the processor supports X86-64 instructions. bool HasX86_64; - /// HasPOPCNT - True if the processor supports POPCNT. + /// True if the processor supports POPCNT. bool HasPOPCNT; - /// HasSSE4A - True if the processor supports SSE4A instructions. + /// True if the processor supports SSE4A instructions. bool HasSSE4A; - /// HasAES - Target has AES instructions + /// Target has AES instructions bool HasAES; - /// HasPCLMUL - Target has carry-less multiplication + /// Target has carry-less multiplication bool HasPCLMUL; - /// HasFMA - Target has 3-operand fused multiply-add + /// Target has 3-operand fused multiply-add bool HasFMA; - /// HasFMA4 - Target has 4-operand fused multiply-add + /// Target has 4-operand fused multiply-add bool HasFMA4; - /// HasXOP - Target has XOP instructions + /// Target has XOP instructions bool HasXOP; - /// HasMOVBE - True if the processor has the MOVBE instruction. + /// Target has TBM instructions. + bool HasTBM; + + /// True if the processor has the MOVBE instruction. bool HasMOVBE; - /// HasRDRAND - True if the processor has the RDRAND instruction. + /// True if the processor has the RDRAND instruction. bool HasRDRAND; - /// HasF16C - Processor has 16-bit floating point conversion instructions. + /// Processor has 16-bit floating point conversion instructions. bool HasF16C; - /// HasFSGSBase - Processor has FS/GS base insturctions. + /// Processor has FS/GS base insturctions. bool HasFSGSBase; - /// HasLZCNT - Processor has LZCNT instruction. + /// Processor has LZCNT instruction. bool HasLZCNT; - /// HasBMI - Processor has BMI1 instructions. + /// Processor has BMI1 instructions. bool HasBMI; - /// HasBMI2 - Processor has BMI2 instructions. + /// Processor has BMI2 instructions. bool HasBMI2; - /// IsBTMemSlow - True if BT (bit test) of memory instructions are slow. + /// Processor has RTM instructions. + bool HasRTM; + + /// Processor has HLE. + bool HasHLE; + + /// Processor has ADX instructions. + bool HasADX; + + /// Processor has SHA instructions. + bool HasSHA; + + /// Processor has PRFCHW instructions. + bool HasPRFCHW; + + /// Processor has RDSEED instructions. + bool HasRDSEED; + + /// True if BT (bit test) of memory instructions are slow. bool IsBTMemSlow; - /// IsUAMemFast - True if unaligned memory access is fast. + /// True if SHLD instructions are slow. + bool IsSHLDSlow; + + /// True if unaligned memory access is fast. bool IsUAMemFast; - /// HasVectorUAMem - True if SIMD operations can have unaligned memory - /// operands. This may require setting a feature bit in the processor. - bool HasVectorUAMem; + /// True if unaligned 32-byte memory accesses are slow. + bool IsUAMem32Slow; + + /// True if SSE operations can have unaligned memory operands. + /// This may require setting a configuration bit in the processor. + bool HasSSEUnalignedMem; - /// HasCmpxchg16b - True if this processor has the CMPXCHG16B instruction; + /// True if this processor has the CMPXCHG16B instruction; /// this is true for most x86-64 chips, but not the first AMD chips. bool HasCmpxchg16b; - /// UseLeaForSP - True if the LEA instruction should be used for adjusting + /// True if the LEA instruction should be used for adjusting /// the stack pointer. This is an optimization for Intel Atom processors. bool UseLeaForSP; - /// HasSlowDivide - True if smaller divides are significantly faster than - /// full divides and should be used when possible. - bool HasSlowDivide; + /// True if 8-bit divisions are significantly faster than + /// 32-bit divisions and should be used when possible. + bool HasSlowDivide32; + + /// True if 16-bit divides are significantly faster than + /// 64-bit divisions and should be used when possible. + bool HasSlowDivide64; + + /// True if the short functions should be padded to prevent + /// a stall when returning too early. + bool PadShortFunctions; + + /// True if the Calls with memory reference should be converted + /// to a register-based indirect call. + bool CallRegIndirect; + + /// True if the LEA instruction inputs have to be ready at address generation + /// (AG) time. + bool LEAUsesAG; + + /// True if the LEA instruction with certain arguments is slow + bool SlowLEA; + + /// True if INC and DEC instructions are slow when writing to flags + bool SlowIncDec; - /// PostRAScheduler - True if using post-register-allocation scheduler. - bool PostRAScheduler; + /// Processor has AVX-512 PreFetch Instructions + bool HasPFI; - /// stackAlignment - The minimum alignment known to hold of the stack frame on + /// Processor has AVX-512 Exponential and Reciprocal Instructions + bool HasERI; + + /// Processor has AVX-512 Conflict Detection Instructions + bool HasCDI; + + /// Processor has AVX-512 Doubleword and Quadword instructions + bool HasDQI; + + /// Processor has AVX-512 Byte and Word instructions + bool HasBWI; + + /// Processor has AVX-512 Vector Length eXtenstions + bool HasVLX; + + /// Processot supports MPX - Memory Protection Extensions + bool HasMPX; + + /// Use software floating point for code generation. + bool UseSoftFloat; + + /// The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. unsigned stackAlignment; @@ -151,31 +222,60 @@ protected: /// unsigned MaxInlineSizeThreshold; - /// TargetTriple - What processor and OS we're targeting. + /// What processor and OS we're targeting. Triple TargetTriple; /// Instruction itineraries for scheduling InstrItineraryData InstrItins; private: - /// In64BitMode - True if compiling for 64-bit, false for 32-bit. + + /// Override the stack alignment. + unsigned StackAlignOverride; + + /// True if compiling for 64-bit, false for 16-bit or 32-bit. bool In64BitMode; -public: + /// True if compiling for 32-bit, false for 16-bit or 64-bit. + bool In32BitMode; + + /// True if compiling for 16-bit, false for 32-bit or 64-bit. + bool In16BitMode; + + X86SelectionDAGInfo TSInfo; + // Ordering here is important. X86InstrInfo initializes X86RegisterInfo which + // X86TargetLowering needs. + X86InstrInfo InstrInfo; + X86TargetLowering TLInfo; + X86FrameLowering FrameLowering; +public: /// This constructor initializes the data members to match that /// of the specified triple. /// - X86Subtarget(const std::string &TT, const std::string &CPU, - const std::string &FS, - unsigned StackAlignOverride, bool is64Bit); + X86Subtarget(const Triple &TT, const std::string &CPU, const std::string &FS, + const X86TargetMachine &TM, unsigned StackAlignOverride); + + const X86TargetLowering *getTargetLowering() const override { + return &TLInfo; + } + const X86InstrInfo *getInstrInfo() const override { return &InstrInfo; } + const X86FrameLowering *getFrameLowering() const override { + return &FrameLowering; + } + const X86SelectionDAGInfo *getSelectionDAGInfo() const override { + return &TSInfo; + } + const X86RegisterInfo *getRegisterInfo() const override { + return &getInstrInfo()->getRegisterInfo(); + } - /// getStackAlignment - Returns the minimum alignment known to hold of the + /// Returns the minimum alignment known to hold of the /// stack frame on entry to the function and which must be maintained by every /// function for this subtarget. unsigned getStackAlignment() const { return stackAlignment; } - /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size + /// Returns the maximum memset / memcpy size /// that still makes it profitable to inline the call. unsigned getMaxInlineSizeThreshold() const { return MaxInlineSizeThreshold; } @@ -183,11 +283,37 @@ public: /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef FS); - /// AutoDetectSubtargetFeatures - Auto-detect CPU features using CPUID - /// instruction. - void AutoDetectSubtargetFeatures(); +private: + /// Initialize the full set of dependencies so we can use an initializer + /// list for X86Subtarget. + X86Subtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); + void initializeEnvironment(); + void initSubtargetFeatures(StringRef CPU, StringRef FS); +public: + /// Is this x86_64? (disregarding specific ABI / programming model) + bool is64Bit() const { + return In64BitMode; + } + + bool is32Bit() const { + return In32BitMode; + } + + bool is16Bit() const { + return In16BitMode; + } + + /// Is this x86_64 with the ILP32 programming model (x32 ABI)? + bool isTarget64BitILP32() const { + return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32 || + TargetTriple.isOSNaCl()); + } - bool is64Bit() const { return In64BitMode; } + /// Is this x86_64 with the LP64 programming model (standard AMD64, no x32)? + bool isTarget64BitLP64() const { + return In64BitMode && (TargetTriple.getEnvironment() != Triple::GNUX32 && + !TargetTriple.isOSNaCl()); + } PICStyles::Style getPICStyle() const { return PICStyle; } void setPICStyle(PICStyles::Style Style) { PICStyle = Style; } @@ -202,7 +328,9 @@ public: bool hasSSE42() const { return X86SSELevel >= SSE42; } bool hasAVX() const { return X86SSELevel >= AVX; } bool hasAVX2() const { return X86SSELevel >= AVX2; } - bool hasNoAVX() const { return X86SSELevel < AVX; } + bool hasAVX512() const { return X86SSELevel >= AVX512F; } + bool hasFp256() const { return hasAVX(); } + bool hasInt256() const { return hasAVX2(); } bool hasSSE4A() const { return HasSSE4A; } bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } @@ -213,6 +341,7 @@ public: // FIXME: Favor FMA when both are enabled. Is this the right thing to do? bool hasFMA4() const { return HasFMA4 && !HasFMA; } bool hasXOP() const { return HasXOP; } + bool hasTBM() const { return HasTBM; } bool hasMOVBE() const { return HasMOVBE; } bool hasRDRAND() const { return HasRDRAND; } bool hasF16C() const { return HasF16C; } @@ -220,50 +349,85 @@ public: bool hasLZCNT() const { return HasLZCNT; } bool hasBMI() const { return HasBMI; } bool hasBMI2() const { return HasBMI2; } + bool hasRTM() const { return HasRTM; } + bool hasHLE() const { return HasHLE; } + bool hasADX() const { return HasADX; } + bool hasSHA() const { return HasSHA; } + bool hasPRFCHW() const { return HasPRFCHW; } + bool hasRDSEED() const { return HasRDSEED; } bool isBTMemSlow() const { return IsBTMemSlow; } + bool isSHLDSlow() const { return IsSHLDSlow; } bool isUnalignedMemAccessFast() const { return IsUAMemFast; } - bool hasVectorUAMem() const { return HasVectorUAMem; } + bool isUnalignedMem32Slow() const { return IsUAMem32Slow; } + bool hasSSEUnalignedMem() const { return HasSSEUnalignedMem; } bool hasCmpxchg16b() const { return HasCmpxchg16b; } bool useLeaForSP() const { return UseLeaForSP; } - bool hasSlowDivide() const { return HasSlowDivide; } + bool hasSlowDivide32() const { return HasSlowDivide32; } + bool hasSlowDivide64() const { return HasSlowDivide64; } + bool padShortFunctions() const { return PadShortFunctions; } + bool callRegIndirect() const { return CallRegIndirect; } + bool LEAusesAG() const { return LEAUsesAG; } + bool slowLEA() const { return SlowLEA; } + bool slowIncDec() const { return SlowIncDec; } + bool hasCDI() const { return HasCDI; } + bool hasPFI() const { return HasPFI; } + bool hasERI() const { return HasERI; } + bool hasDQI() const { return HasDQI; } + bool hasBWI() const { return HasBWI; } + bool hasVLX() const { return HasVLX; } + bool hasMPX() const { return HasMPX; } bool isAtom() const { return X86ProcFamily == IntelAtom; } + bool isSLM() const { return X86ProcFamily == IntelSLM; } + bool useSoftFloat() const { return UseSoftFloat; } const Triple &getTargetTriple() const { return TargetTriple; } bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } - bool isTargetFreeBSD() const { - return TargetTriple.getOS() == Triple::FreeBSD; - } - bool isTargetSolaris() const { - return TargetTriple.getOS() == Triple::Solaris; - } + bool isTargetFreeBSD() const { return TargetTriple.isOSFreeBSD(); } + bool isTargetDragonFly() const { return TargetTriple.isOSDragonFly(); } + bool isTargetSolaris() const { return TargetTriple.isOSSolaris(); } + bool isTargetPS4() const { return TargetTriple.isPS4(); } - // ELF is a reasonably sane default and the only other X86 targets we - // support are Darwin and Windows. Just use "not those". bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } - bool isTargetLinux() const { return TargetTriple.getOS() == Triple::Linux; } - bool isTargetNaCl() const { - return TargetTriple.getOS() == Triple::NativeClient; - } + bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } + bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } + + bool isTargetLinux() const { return TargetTriple.isOSLinux(); } + bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } - bool isTargetWindows() const { return TargetTriple.getOS() == Triple::Win32; } - bool isTargetMingw() const { return TargetTriple.getOS() == Triple::MinGW32; } - bool isTargetCygwin() const { return TargetTriple.getOS() == Triple::Cygwin; } + + bool isTargetWindowsMSVC() const { + return TargetTriple.isWindowsMSVCEnvironment(); + } + + bool isTargetKnownWindowsMSVC() const { + return TargetTriple.isKnownWindowsMSVCEnvironment(); + } + + bool isTargetWindowsCygwin() const { + return TargetTriple.isWindowsCygwinEnvironment(); + } + + bool isTargetWindowsGNU() const { + return TargetTriple.isWindowsGNUEnvironment(); + } + + bool isTargetWindowsItanium() const { + return TargetTriple.isWindowsItaniumEnvironment(); + } + bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } - bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } - bool isTargetEnvMacho() const { return TargetTriple.isEnvironmentMachO(); } + + bool isOSWindows() const { return TargetTriple.isOSWindows(); } bool isTargetWin64() const { - // FIXME: x86_64-cygwin has not been released yet. return In64BitMode && TargetTriple.isOSWindows(); } bool isTargetWin32() const { - // FIXME: Cygwin is included for isTargetWin64 -- should it be included - // here too? - return !In64BitMode && (isTargetMingw() || isTargetWindows()); + return !In64BitMode && (isTargetCygMing() || isTargetKnownWindowsMSVC()); } bool isPICStyleSet() const { return PICStyle != PICStyles::None; } @@ -279,7 +443,13 @@ public: } bool isPICStyleStubAny() const { return PICStyle == PICStyles::StubDynamicNoPIC || - PICStyle == PICStyles::StubPIC; } + PICStyle == PICStyles::StubPIC; + } + + bool isCallingConvWin64(CallingConv::ID CC) const { + return (isTargetWin64() && CC != CallingConv::X86_64_SysV) || + CC == CallingConv::X86_64_Win64; + } /// ClassifyGlobalReference - Classify a global variable reference for the /// current subtarget according to how we should reference it in a non-pcrel @@ -287,13 +457,11 @@ public: unsigned char ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM)const; - /// ClassifyBlockAddressReference - Classify a blockaddress reference for the - /// current subtarget according to how we should reference it in a non-pcrel - /// context. + /// Classify a blockaddress reference for the current subtarget according to + /// how we should reference it in a non-pcrel context. unsigned char ClassifyBlockAddressReference() const; - /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls - /// to immediate address. + /// Return true if the subtarget allows calls to immediate address. bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const; /// This function returns the name of a function which has an interface @@ -303,24 +471,25 @@ public: /// returns null. const char *getBZeroEntry() const; - /// getSpecialAddressLatency - For targets where it is beneficial to - /// backschedule instructions that compute addresses, return a value - /// indicating the number of scheduling cycles of backscheduling that - /// should be attempted. - unsigned getSpecialAddressLatency() const; + /// This function returns true if the target has sincos() routine in its + /// compiler runtime or math libraries. + bool hasSinCos() const; + + /// Enable the MachineScheduler pass for all X86 subtargets. + bool enableMachineScheduler() const override { return true; } - /// enablePostRAScheduler - run for Atom optimization. - bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, - TargetSubtargetInfo::AntiDepBreakMode& Mode, - RegClassVector& CriticalPathRCs) const; + bool enableEarlyIfConversion() const override; - bool postRAScheduler() const { return PostRAScheduler; } + /// Return the instruction itineraries based on the subtarget selection. + const InstrItineraryData *getInstrItineraryData() const override { + return &InstrItins; + } - /// getInstrItins = Return the instruction itineraries based on the - /// subtarget selection. - const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } + AntiDepBreakMode getAntiDepBreakMode() const override { + return TargetSubtargetInfo::ANTIDEP_CRITICAL; + } }; -} // End llvm namespace +} // namespace llvm #endif