diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 668e57d8601..d9916583abc 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -241,10 +241,11 @@ AddLiveIn(MachineFunction &MF, unsigned PReg, TargetRegisterClass *RC) bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV) { const TargetData *TD = getTargetData(); - const Value *V = dyn_cast(GV); - const GlobalVariable *GVA = dyn_cast(V); + const GlobalVariable *GVA = dyn_cast(GV); + + if (!GVA) + return false; - //const PointerType *PTy = GV->getType(); const Type *Ty = GV->getType()->getElementType(); unsigned Size = TD->getABITypeSize(Ty); diff --git a/lib/Target/Mips/MipsTargetAsmInfo.cpp b/lib/Target/Mips/MipsTargetAsmInfo.cpp index 40c6e7f9545..4678c3b2031 100644 --- a/lib/Target/Mips/MipsTargetAsmInfo.cpp +++ b/lib/Target/Mips/MipsTargetAsmInfo.cpp @@ -19,6 +19,8 @@ using namespace llvm; MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM): ELFTargetAsmInfo(TM) { + MipsTM = &TM; + AlignmentIsInBytes = false; COMMDirectiveTakesAlignment = true; Data16bitsDirective = "\t.half\t"; @@ -37,5 +39,66 @@ MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM): JumpTableDirective = "\t.word\t"; else JumpTableDirective = "\t.gpword\t"; - + + SmallDataSection = getNamedSection("\t.sdata", SectionFlags::Writeable); + SmallBSSSection = getNamedSection("\t.sbss", + SectionFlags::Writeable | SectionFlags::BSS); +} + +static bool isSuitableForBSS(const GlobalVariable *GV) { + if (!GV->hasInitializer()) + return true; + + // Leave constant zeros in readonly constant sections, so they can be shared + Constant *C = GV->getInitializer(); + return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS); +} + +SectionKind::Kind +MipsTargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { + const TargetData *TD = ETM->getTargetData(); + const GlobalVariable *GVA = dyn_cast(GV); + + if (!GVA) + return ELFTargetAsmInfo::SectionKindForGlobal(GV); + + // if this is a internal constant string, there is a special + // section for it, but not in small data/bss. + if (GVA->hasInitializer() && GV->hasInternalLinkage()) { + Constant *C = GVA->getInitializer(); + const ConstantArray *CVA = dyn_cast(C); + if (CVA && CVA->isCString()) + return ELFTargetAsmInfo::SectionKindForGlobal(GV); + } + + const Type *Ty = GV->getType()->getElementType(); + unsigned Size = TD->getABITypeSize(Ty); + unsigned Threshold = + MipsTM->getSubtarget().getSSectionThreshold(); + + if (Size > 0 && Size <= Threshold) { + if (isSuitableForBSS(GVA)) + return SectionKind::SmallBSS; + else + return SectionKind::SmallData; + } + + return ELFTargetAsmInfo::SectionKindForGlobal(GV); +} + +const Section* +MipsTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { + SectionKind::Kind K = SectionKindForGlobal(GV); + const GlobalVariable *GVA = dyn_cast(GV); + + if (GVA && (!GVA->isWeakForLinker())) + switch (K) { + case SectionKind::SmallData: + return getSmallDataSection(); + case SectionKind::SmallBSS: + return getSmallBSSSection(); + default: break; + } + + return ELFTargetAsmInfo::SelectSectionForGlobal(GV); } diff --git a/lib/Target/Mips/MipsTargetAsmInfo.h b/lib/Target/Mips/MipsTargetAsmInfo.h index 994da830ee1..e5bb4d91058 100644 --- a/lib/Target/Mips/MipsTargetAsmInfo.h +++ b/lib/Target/Mips/MipsTargetAsmInfo.h @@ -16,6 +16,9 @@ #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/ELFTargetAsmInfo.h" +#include "llvm/DerivedTypes.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Target/TargetOptions.h" namespace llvm { @@ -24,6 +27,17 @@ namespace llvm { struct MipsTargetAsmInfo : public ELFTargetAsmInfo { explicit MipsTargetAsmInfo(const MipsTargetMachine &TM); + + /// SectionKindForGlobal - This hook allows the target to select proper + /// section kind used for global emission. + virtual SectionKind::Kind + SectionKindForGlobal(const GlobalValue *GV) const; + + virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; + + private: + const MipsTargetMachine *MipsTM; + }; } // namespace llvm