diff options
Diffstat (limited to 'lib/Target/X86/X86Subtarget.cpp')
| -rw-r--r-- | lib/Target/X86/X86Subtarget.cpp | 163 | 
1 files changed, 55 insertions, 108 deletions
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index ad023623142f..7e84323dda4c 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -68,14 +68,36 @@ X86Subtarget::classifyGlobalReference(const GlobalValue *GV) const {  unsigned char  X86Subtarget::classifyLocalReference(const GlobalValue *GV) const { -  // 64 bits can use %rip addressing for anything local. -  if (is64Bit()) +  // If we're not PIC, it's not very interesting. +  if (!isPositionIndependent())      return X86II::MO_NO_FLAG; -  // If this is for a position dependent executable, the static linker can -  // figure it out. -  if (!isPositionIndependent()) +  if (is64Bit()) { +    // 64-bit ELF PIC local references may use GOTOFF relocations. +    if (isTargetELF()) { +      switch (TM.getCodeModel()) { +      // 64-bit small code model is simple: All rip-relative. +      case CodeModel::Small: +      case CodeModel::Kernel: +        return X86II::MO_NO_FLAG; + +      // The large PIC code model uses GOTOFF. +      case CodeModel::Large: +        return X86II::MO_GOTOFF; + +      // Medium is a hybrid: RIP-rel for code, GOTOFF for DSO local data. +      case CodeModel::Medium: +        if (isa<Function>(GV)) +          return X86II::MO_NO_FLAG; // All code is RIP-relative +        return X86II::MO_GOTOFF;    // Local symbols use GOTOFF. +      } +      llvm_unreachable("invalid code model"); +    } + +    // Otherwise, this is either a RIP-relative reference or a 64-bit movabsq, +    // both of which use MO_NO_FLAG.      return X86II::MO_NO_FLAG; +  }    // The COFF dynamic linker just patches the executable sections.    if (isTargetCOFF()) @@ -97,8 +119,8 @@ X86Subtarget::classifyLocalReference(const GlobalValue *GV) const {  unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,                                                      const Module &M) const { -  // Large model never uses stubs. -  if (TM.getCodeModel() == CodeModel::Large) +  // The static large model never uses stubs. +  if (TM.getCodeModel() == CodeModel::Large && !isPositionIndependent())      return X86II::MO_NO_FLAG;    // Absolute symbols can be referenced directly. @@ -120,8 +142,14 @@ unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,    if (isTargetCOFF())      return X86II::MO_DLLIMPORT; -  if (is64Bit()) +  if (is64Bit()) { +    // ELF supports a large, truly PIC code model with non-PC relative GOT +    // references. Other object file formats do not. Use the no-flag, 64-bit +    // reference for them. +    if (TM.getCodeModel() == CodeModel::Large) +      return isTargetELF() ? X86II::MO_GOT : X86II::MO_NO_FLAG;      return X86II::MO_GOTPCREL; +  }    if (isTargetDarwin()) {      if (!isPositionIndependent()) @@ -157,8 +185,11 @@ X86Subtarget::classifyGlobalFunctionReference(const GlobalValue *GV,        // In Regcall calling convention those registers are used for passing        // parameters. Thus we need to prevent lazy binding in Regcall.        return X86II::MO_GOTPCREL; -    if (F && F->hasFnAttribute(Attribute::NonLazyBind) && is64Bit()) -      return X86II::MO_GOTPCREL; +    // If PLT must be avoided then the call should be via GOTPCREL. +    if (((F && F->hasFnAttribute(Attribute::NonLazyBind)) || +         (!F && M.getRtLibUseGOT())) && +        is64Bit()) +       return X86II::MO_GOTPCREL;      return X86II::MO_PLT;    } @@ -216,8 +247,6 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {    // micro-architectures respectively.    if (hasSSE42() || hasSSE4A())      IsUAMem16Slow = false; -   -  InstrItins = getInstrItineraryForCPU(CPUName);    // It's important to keep the MCSubtargetInfo feature bits in sync with    // target data structure which is shared with MC code emitter, etc. @@ -230,9 +259,9 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {    else      llvm_unreachable("Not 16-bit, 32-bit or 64-bit mode!"); -  DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel -               << ", 3DNowLevel " << X863DNowLevel -               << ", 64bit " << HasX86_64 << "\n"); +  LLVM_DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel +                    << ", 3DNowLevel " << X863DNowLevel << ", 64bit " +                    << HasX86_64 << "\n");    assert((!In64BitMode || HasX86_64) &&           "64-bit code requested on a subtarget that doesn't support it!"); @@ -254,112 +283,30 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {      GatherOverhead = 2;    if (hasAVX512())      ScatterOverhead = 2; -} -void X86Subtarget::initializeEnvironment() { -  X86SSELevel = NoSSE; -  X863DNowLevel = NoThreeDNow; -  HasX87 = false; -  HasCMov = false; -  HasX86_64 = false; -  HasPOPCNT = false; -  HasSSE4A = false; -  HasAES = false; -  HasVAES = false; -  HasFXSR = false; -  HasXSAVE = false; -  HasXSAVEOPT = false; -  HasXSAVEC = false; -  HasXSAVES = false; -  HasPCLMUL = false; -  HasVPCLMULQDQ = false; -  HasGFNI = false; -  HasFMA = false; -  HasFMA4 = false; -  HasXOP = false; -  HasTBM = false; -  HasLWP = false; -  HasMOVBE = false; -  HasRDRAND = false; -  HasF16C = false; -  HasFSGSBase = false; -  HasLZCNT = false; -  HasBMI = false; -  HasBMI2 = false; -  HasVBMI = false; -  HasVBMI2 = false; -  HasIFMA = false; -  HasRTM = false; -  HasERI = false; -  HasCDI = false; -  HasPFI = false; -  HasDQI = false; -  HasVPOPCNTDQ = false; -  HasBWI = false; -  HasVLX = false; -  HasADX = false; -  HasPKU = false; -  HasVNNI = false; -  HasBITALG = false; -  HasSHA = false; -  HasPREFETCHWT1 = false; -  HasPRFCHW = false; -  HasRDSEED = false; -  HasLAHFSAHF = false; -  HasMWAITX = false; -  HasCLZERO = false; -  HasMPX = false; -  HasSHSTK = false; -  HasIBT = false; -  HasSGX = false; -  HasCLFLUSHOPT = false; -  HasCLWB = false; -  IsPMULLDSlow = false; -  IsSHLDSlow = false; -  IsUAMem16Slow = false; -  IsUAMem32Slow = false; -  HasSSEUnalignedMem = false; -  HasCmpxchg16b = false; -  UseLeaForSP = false; -  HasFastVariableShuffle = false; -  HasFastPartialYMMorZMMWrite = false; -  HasFastGather = false; -  HasFastScalarFSQRT = false; -  HasFastVectorFSQRT = false; -  HasFastLZCNT = false; -  HasFastSHLDRotate = false; -  HasMacroFusion = false; -  HasERMSB = false; -  HasSlowDivide32 = false; -  HasSlowDivide64 = false; -  PadShortFunctions = false; -  SlowTwoMemOps = false; -  LEAUsesAG = false; -  SlowLEA = false; -  Slow3OpsLEA = false; -  SlowIncDec = false; -  stackAlignment = 4; -  // FIXME: this is a known good value for Yonah. How about others? -  MaxInlineSizeThreshold = 128; -  UseSoftFloat = false; -  X86ProcFamily = Others; -  GatherOverhead = 1024; -  ScatterOverhead = 1024; +  // Consume the vector width attribute or apply any target specific limit. +  if (PreferVectorWidthOverride) +    PreferVectorWidth = PreferVectorWidthOverride; +  else if (Prefer256Bit) +    PreferVectorWidth = 256;  }  X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU,                                                              StringRef FS) { -  initializeEnvironment();    initSubtargetFeatures(CPU, FS);    return *this;  }  X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,                             const X86TargetMachine &TM, -                           unsigned StackAlignOverride) -    : X86GenSubtargetInfo(TT, CPU, FS), X86ProcFamily(Others), +                           unsigned StackAlignOverride, +                           unsigned PreferVectorWidthOverride, +                           unsigned RequiredVectorWidth) +    : X86GenSubtargetInfo(TT, CPU, FS),        PICStyle(PICStyles::None), TM(TM), TargetTriple(TT),        StackAlignOverride(StackAlignOverride), +      PreferVectorWidthOverride(PreferVectorWidthOverride), +      RequiredVectorWidth(RequiredVectorWidth),        In64BitMode(TargetTriple.getArch() == Triple::x86_64),        In32BitMode(TargetTriple.getArch() == Triple::x86 &&                    TargetTriple.getEnvironment() != Triple::CODE16),  | 
