diff --git a/include/llvm/Target/DarwinTargetAsmInfo.h b/include/llvm/Target/DarwinTargetAsmInfo.h index 8eef95dfa4c..edce64096a9 100644 --- a/include/llvm/Target/DarwinTargetAsmInfo.h +++ b/include/llvm/Target/DarwinTargetAsmInfo.h @@ -39,7 +39,10 @@ namespace llvm { SectionKind::Kind kind) const; virtual bool emitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const; - const Section* SelectSectionForMachineConst(const Type *Ty) const; + + + virtual const Section * + getSectionForMergableConstant(uint64_t Size, unsigned ReloInfo) const; private: const Section* MergeableConstSection(const Type *Ty) const; diff --git a/include/llvm/Target/ELFTargetAsmInfo.h b/include/llvm/Target/ELFTargetAsmInfo.h index fd269a14306..c06a5a9f287 100644 --- a/include/llvm/Target/ELFTargetAsmInfo.h +++ b/include/llvm/Target/ELFTargetAsmInfo.h @@ -25,11 +25,16 @@ namespace llvm { struct ELFTargetAsmInfo: public TargetAsmInfo { explicit ELFTargetAsmInfo(const TargetMachine &TM); + /// getSectionForMergableConstant - Given a mergable constant with the + /// specified size and relocation information, return a section that it + /// should be placed in. + virtual const Section * + getSectionForMergableConstant(uint64_t Size, unsigned ReloInfo) const; + + SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; virtual std::string printSectionFlags(unsigned flags) const; - virtual const Section* - SelectSectionForMachineConst(const Type *Ty) const; const Section* DataRelSection; const Section* DataRelLocalSection; diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index e59b12a7cd2..01404334138 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -595,6 +595,14 @@ namespace llvm { virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, bool Global) const; + + /// getSectionForMergableConstant - Given a mergable constant with the + /// specified size and relocation information, return a section that it + /// should be placed in. + virtual const Section * + getSectionForMergableConstant(uint64_t Size, unsigned ReloInfo) const; + + /// SectionKindForGlobal - This hook allows the target to select proper /// section kind used for global emission. // FIXME: Eliminate this. @@ -623,7 +631,6 @@ namespace llvm { // FIXME: Eliminate this. virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; - virtual const Section* SelectSectionForMachineConst(const Type *Ty) const; /// getSLEB128Size - Compute the number of bytes required for a signed /// leb128 value. diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 7b7a9a5a97a..e31a39c7a39 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -302,13 +302,18 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { const std::vector &CP = MCP->getConstants(); if (CP.empty()) return; + const TargetData &TD = *TM.getTargetData(); + // Calculate sections for constant pool entries. We collect entries to go into // the same section together to reduce amount of section switch statements. SmallVector CPSections; for (unsigned i = 0, e = CP.size(); i != e; ++i) { - MachineConstantPoolEntry CPE = CP[i]; + const MachineConstantPoolEntry &CPE = CP[i]; unsigned Align = CPE.getAlignment(); - const Section* S = TAI->SelectSectionForMachineConst(CPE.getType()); + uint64_t Size = TD.getTypeAllocSize(CPE.getType()); + const Section *S = + TAI->getSectionForMergableConstant(Size, CPE.getRelocationInfo()); + // The number of sections are small, just do a linear search from the // last section to the first. bool Found = false; diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index f4cd94a988a..8cbaf6f13bd 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -155,8 +155,10 @@ ELFSection &ELFWriter::getJumpTableSection() { // Get a constant pool section based on the section name returned by TAI ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) { + uint64_t Size = TM.getTargetData()->getTypeAllocSize(CPE.getType()); + std::string CstPoolName = - TAI->SelectSectionForMachineConst(CPE.getType())->getName(); + TAI->getSectionForMergableConstant(Size,CPE.getRelocationInfo())->getName(); return getSection(CstPoolName, ELFSection::SHT_PROGBITS, ELFSection::SHF_MERGE | ELFSection::SHF_ALLOC, diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp index 30468efe3e3..ad9dd6884f4 100644 --- a/lib/Target/DarwinTargetAsmInfo.cpp +++ b/lib/Target/DarwinTargetAsmInfo.cpp @@ -29,7 +29,7 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) : TargetAsmInfo(TM) { CStringSection_ = getUnnamedSection("\t.cstring", - SectionFlags::Mergeable | SectionFlags::Strings); + SectionFlags::Mergeable |SectionFlags::Strings); FourByteConstantSection = getUnnamedSection("\t.literal4\n", SectionFlags::Mergeable); EightByteConstantSection = getUnnamedSection("\t.literal8\n", @@ -182,28 +182,30 @@ DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { const Section* DarwinTargetAsmInfo::MergeableConstSection(const Type *Ty) const { const TargetData *TD = TM.getTargetData(); - - unsigned Size = TD->getTypeAllocSize(Ty); - if (Size == 4) - return FourByteConstantSection; - else if (Size == 8) - return EightByteConstantSection; - else if (Size == 16 && SixteenByteConstantSection) - return SixteenByteConstantSection; - - return getReadOnlySection(); + return getSectionForMergableConstant(TD->getTypeAllocSize(Ty), 0); } -const Section* -DarwinTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { - const Section* S = MergeableConstSection(Ty); - - // Handle weird special case, when compiling PIC stuff. - if (S == getReadOnlySection() && - TM.getRelocationModel() != Reloc::Static) +const Section * +DarwinTargetAsmInfo::getSectionForMergableConstant(uint64_t Size, + unsigned ReloInfo) const { + // If this constant requires a relocation, we have to put it in the data + // segment, not in the text segment. + if (ReloInfo != 0) return ConstDataSection; - - return S; + + switch (Size) { + default: break; + case 4: + return FourByteConstantSection; + case 8: + return EightByteConstantSection; + case 16: + if (SixteenByteConstantSection) + return SixteenByteConstantSection; + break; + } + + return ReadOnlySection; // .const } std::string diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp index 1bcfaf91ad0..fe006a3c607 100644 --- a/lib/Target/ELFTargetAsmInfo.cpp +++ b/lib/Target/ELFTargetAsmInfo.cpp @@ -138,29 +138,37 @@ ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { return NULL; } -const Section* -ELFTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { - // FIXME: Support data.rel stuff someday - return MergeableConstSection(Ty); +/// getSectionForMergableConstant - Given a mergable constant with the +/// specified size and relocation information, return a section that it +/// should be placed in. +const Section * +ELFTargetAsmInfo::getSectionForMergableConstant(uint64_t Size, + unsigned ReloInfo) const { + // FIXME: IF this global requires a relocation, can we really put it in + // rodata??? This should check ReloInfo like darwin. + + const char *SecName = 0; + switch (Size) { + default: break; + case 4: SecName = ".rodata.cst4"; break; + case 8: SecName = ".rodata.cst8"; break; + case 16: SecName = ".rodata.cst16"; break; + } + + if (SecName) + return getNamedSection(SecName, + SectionFlags::setEntitySize(SectionFlags::Mergeable| + SectionFlags::Small, + Size)); + + return getReadOnlySection(); // .rodata } + const Section* ELFTargetAsmInfo::MergeableConstSection(const Type *Ty) const { const TargetData *TD = TM.getTargetData(); - - // FIXME: string here is temporary, until stuff will fully land in. - // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's - // currently directly used by asmprinter. - unsigned Size = TD->getTypeAllocSize(Ty); - if (Size == 4 || Size == 8 || Size == 16) { - std::string Name = ".rodata.cst" + utostr(Size); - - return getNamedSection(Name.c_str(), - SectionFlags::setEntitySize(SectionFlags::Mergeable, - Size)); - } - - return getReadOnlySection(); + return getSectionForMergableConstant(TD->getTypeAllocSize(Ty), 0); } const Section* diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 96814fee4c9..d8c331eb404 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -329,13 +329,20 @@ TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { return getDataSection(); } -// Lame default implementation. Calculate the section name for machine const. -const Section* -TargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { +/// getSectionForMergableConstant - Given a mergable constant with the +/// specified size and relocation information, return a section that it +/// should be placed in. +const Section * +TargetAsmInfo::getSectionForMergableConstant(uint64_t Size, + unsigned ReloInfo) const { // FIXME: Support data.rel stuff someday + // Lame default implementation. Calculate the section name for machine const. return getDataSection(); } + + + std::string TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, SectionKind::Kind Kind) const {