diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2008-07-22 15:34:27 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2008-07-22 15:34:27 +0000 |
commit | feb95cc7e3e557f6d803a8c03a0b37ec4691d474 (patch) | |
tree | 80ecb5a86706b6c6d8c1a1aba1de4a8d84609cc1 /lib | |
parent | 62d590cc8e8ce10351fa20b8cde77f511b8bdb74 (diff) | |
download | llvm-feb95cc7e3e557f6d803a8c03a0b37ec4691d474.tar.gz llvm-feb95cc7e3e557f6d803a8c03a0b37ec4691d474.tar.bz2 llvm-feb95cc7e3e557f6d803a8c03a0b37ec4691d474.tar.xz |
Added small section asm emition logic for mips.
Fixed small bug.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53908 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 7 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetAsmInfo.cpp | 63 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetAsmInfo.h | 14 |
3 files changed, 81 insertions, 3 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 668e57d860..d9916583ab 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<Value>(GV); - const GlobalVariable *GVA = dyn_cast<GlobalVariable>(V); + const GlobalVariable *GVA = dyn_cast<GlobalVariable>(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 40c6e7f954..4678c3b203 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<GlobalVariable>(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<ConstantArray>(C); + if (CVA && CVA->isCString()) + return ELFTargetAsmInfo::SectionKindForGlobal(GV); + } + + const Type *Ty = GV->getType()->getElementType(); + unsigned Size = TD->getABITypeSize(Ty); + unsigned Threshold = + MipsTM->getSubtarget<MipsSubtarget>().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<GlobalVariable>(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 994da830ee..e5bb4d9105 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 |