diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp')
| -rw-r--r-- | contrib/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp | 73 | 
1 files changed, 59 insertions, 14 deletions
| diff --git a/contrib/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp b/contrib/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp index 13f9408f4e6e..b56c39bf496c 100644 --- a/contrib/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp +++ b/contrib/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp @@ -24,6 +24,17 @@ SSThreshold("mips-ssection-threshold", cl::Hidden,              cl::desc("Small data and bss section threshold size (default=8)"),              cl::init(8)); +static cl::opt<bool> +LocalSData("mlocal-sdata", cl::Hidden, +           cl::desc("MIPS: Use gp_rel for object-local data."), +           cl::init(true)); + +static cl::opt<bool> +ExternSData("mextern-sdata", cl::Hidden, +            cl::desc("MIPS: Use gp_rel for data that is not defined by the " +                     "current object."), +            cl::init(true)); +  void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){    TargetLoweringObjectFileELF::Initialize(Ctx, TM);    InitializeELF(TM.Options.UseInitArray); @@ -37,29 +48,46 @@ void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){      getContext().getELFSection(".sbss", ELF::SHT_NOBITS,                                 ELF::SHF_WRITE |ELF::SHF_ALLOC,                                 SectionKind::getBSS()); +  this->TM = &TM;  }  // A address must be loaded from a small section if its size is less than the  // small section size threshold. Data in this section must be addressed using  // gp_rel operator.  static bool IsInSmallSection(uint64_t Size) { +  // gcc has traditionally not treated zero-sized objects as small data, so this +  // is effectively part of the ABI.    return Size > 0 && Size <= SSThreshold;  } -bool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV, -                                                const TargetMachine &TM) const { +/// Return true if this global address should be placed into small data/bss +/// section. +bool MipsTargetObjectFile:: +IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const { +  // We first check the case where global is a declaration, because finding +  // section kind using getKindForGlobal() is only allowed for global +  // definitions.    if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) -    return false; +    return IsGlobalInSmallSectionImpl(GV, TM);    return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));  } -/// IsGlobalInSmallSection - Return true if this global address should be -/// placed into small data/bss section. +/// Return true if this global address should be placed into small data/bss +/// section.  bool MipsTargetObjectFile::  IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,                         SectionKind Kind) const { +  return (IsGlobalInSmallSectionImpl(GV, TM) && +          (Kind.isDataRel() || Kind.isBSS() || Kind.isCommon())); +} +/// Return true if this global address should be placed into small data/bss +/// section. This method does all the work, except for checking the section +/// kind. +bool MipsTargetObjectFile:: +IsGlobalInSmallSectionImpl(const GlobalValue *GV, +                           const TargetMachine &TM) const {    const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();    // Return if small section is not available. @@ -71,21 +99,20 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,    if (!GVA)      return false; -  // We can only do this for datarel or BSS objects for now. -  if (!Kind.isBSS() && !Kind.isDataRel()) +  // Enforce -mlocal-sdata. +  if (!LocalSData && GV->hasLocalLinkage())      return false; -  // If this is a internal constant string, there is a special -  // section for it, but not in small data/bss. -  if (Kind.isMergeable1ByteCString()) +  // Enforce -mextern-sdata. +  if (!ExternSData && ((GV->hasExternalLinkage() && GV->isDeclaration()) || +                       GV->hasCommonLinkage()))      return false;    Type *Ty = GV->getType()->getElementType(); -  return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty)); +  return IsInSmallSection( +      TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(Ty));  } - -  const MCSection *MipsTargetObjectFile::  SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,                         Mangler &Mang, const TargetMachine &TM) const { @@ -95,9 +122,27 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,    // Handle Small Section classification here.    if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))      return SmallBSSSection; -  if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind)) +  if (Kind.isDataRel() && IsGlobalInSmallSection(GV, TM, Kind))      return SmallDataSection;    // Otherwise, we work the same as ELF.    return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);  } + +/// Return true if this constant should be placed into small data section. +bool MipsTargetObjectFile:: +IsConstantInSmallSection(const Constant *CN, const TargetMachine &TM) const { +  return (TM.getSubtarget<MipsSubtarget>().useSmallSection() && +          LocalSData && +          IsInSmallSection(TM.getSubtargetImpl()->getDataLayout() +                           ->getTypeAllocSize(CN->getType()))); +} + +const MCSection *MipsTargetObjectFile:: +getSectionForConstant(SectionKind Kind, const Constant *C) const { +  if (IsConstantInSmallSection(C, *TM)) +    return SmallDataSection; + +  // Otherwise, we work the same as ELF. +  return TargetLoweringObjectFileELF::getSectionForConstant(Kind, C); +} | 
