diff options
Diffstat (limited to 'lib/Target/Mips/MipsTargetObjectFile.cpp')
| -rw-r--r-- | lib/Target/Mips/MipsTargetObjectFile.cpp | 33 | 
1 files changed, 31 insertions, 2 deletions
diff --git a/lib/Target/Mips/MipsTargetObjectFile.cpp b/lib/Target/Mips/MipsTargetObjectFile.cpp index 4d73c3991035..9db6b7b1bcd6 100644 --- a/lib/Target/Mips/MipsTargetObjectFile.cpp +++ b/lib/Target/Mips/MipsTargetObjectFile.cpp @@ -36,6 +36,12 @@ ExternSData("mextern-sdata", cl::Hidden,                       "current object."),              cl::init(true)); +static cl::opt<bool> +EmbeddedData("membedded-data", cl::Hidden, +             cl::desc("MIPS: Try to allocate variables in the following" +                      " sections if possible: .rodata, .sdata, .data ."), +             cl::init(false)); +  void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){    TargetLoweringObjectFileELF::Initialize(Ctx, TM);    InitializeELF(TM.Options.UseInitArray); @@ -77,8 +83,9 @@ bool MipsTargetObjectFile::IsGlobalInSmallSection(  bool MipsTargetObjectFile::  IsGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM,                         SectionKind Kind) const { -  return (IsGlobalInSmallSectionImpl(GO, TM) && -          (Kind.isData() || Kind.isBSS() || Kind.isCommon())); +  return IsGlobalInSmallSectionImpl(GO, TM) && +         (Kind.isData() || Kind.isBSS() || Kind.isCommon() || +          Kind.isReadOnly());  }  /// Return true if this global address should be placed into small data/bss @@ -99,6 +106,22 @@ IsGlobalInSmallSectionImpl(const GlobalObject *GO,    if (!GVA)      return false; +  // If the variable has an explicit section, it is placed in that section but +  // it's addressing mode may change. +  if (GVA->hasSection()) { +    StringRef Section = GVA->getSection(); + +    // Explicitly placing any variable in the small data section overrides +    // the global -G value. +    if (Section == ".sdata" || Section == ".sbss") +      return true; + +    // Otherwise reject accessing it through the gp pointer. There are some +    // historic cases which GCC doesn't appear to respect any more. These +    // are .lit4, .lit8 and .srdata. For the moment reject these as well. +    return false; +  } +    // Enforce -mlocal-sdata.    if (!LocalSData && GVA->hasLocalLinkage())      return false; @@ -108,6 +131,10 @@ IsGlobalInSmallSectionImpl(const GlobalObject *GO,                         GVA->hasCommonLinkage()))      return false; +  // Enforce -membedded-data. +  if (EmbeddedData && GVA->isConstant()) +    return false; +    Type *Ty = GVA->getValueType();    return IsInSmallSection(        GVA->getParent()->getDataLayout().getTypeAllocSize(Ty)); @@ -123,6 +150,8 @@ MCSection *MipsTargetObjectFile::SelectSectionForGlobal(      return SmallBSSSection;    if (Kind.isData() && IsGlobalInSmallSection(GO, TM, Kind))      return SmallDataSection; +  if (Kind.isReadOnly() && IsGlobalInSmallSection(GO, TM, Kind)) +    return SmallDataSection;    // Otherwise, we work the same as ELF.    return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);  | 
