From: Chris Lattner Date: Fri, 24 Jul 2009 19:15:47 +0000 (+0000) Subject: make SectionKindForGlobal target independent, and therefore non-virtual. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=b303504a562c98b3ce465d0bfcbd3d9334193e1f;p=oota-llvm.git make SectionKindForGlobal target independent, and therefore non-virtual. It's classifications now include elf-specific discriminators. Targets that don't have these features (like darwin and pecoff) simply treat data.rel like data, etc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76993 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Target/ELFTargetAsmInfo.h b/include/llvm/Target/ELFTargetAsmInfo.h index 63e3acd50d7..54220e765fd 100644 --- a/include/llvm/Target/ELFTargetAsmInfo.h +++ b/include/llvm/Target/ELFTargetAsmInfo.h @@ -37,7 +37,6 @@ namespace llvm { /// ".tbss" gets the TLS bit set etc. virtual unsigned getFlagsForNamedSection(const char *Section) const; - SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV, SectionKind::Kind Kind) const; virtual std::string printSectionFlags(unsigned flags) const; diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index a34911691a8..322c57f4db5 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -611,8 +611,7 @@ namespace llvm { /// SectionKindForGlobal - This hook allows the target to select proper /// section kind used for global emission. // FIXME: Eliminate this. - virtual SectionKind::Kind - SectionKindForGlobal(const GlobalValue *GV) const; + SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV) const; const std::string &getSectionFlags(unsigned Flags) const; diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp index 27714f21ea0..2d3c5ff3468 100644 --- a/lib/Target/DarwinTargetAsmInfo.cpp +++ b/lib/Target/DarwinTargetAsmInfo.cpp @@ -131,19 +131,24 @@ DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV, bool isNonStatic = TM.getRelocationModel() != Reloc::Static; switch (Kind) { + case SectionKind::ThreadData: + case SectionKind::ThreadBSS: + llvm_unreachable("Darwin doesn't support TLS"); case SectionKind::Text: if (isWeak) return TextCoalSection; return TextSection; case SectionKind::Data: - case SectionKind::ThreadData: + case SectionKind::DataRelLocal: + case SectionKind::DataRel: case SectionKind::BSS: - case SectionKind::ThreadBSS: if (cast(GV)->isConstant()) return isWeak ? ConstDataCoalSection : ConstDataSection; return isWeak ? DataCoalSection : DataSection; case SectionKind::ROData: + case SectionKind::DataRelRO: + case SectionKind::DataRelROLocal: return (isWeak ? ConstDataCoalSection : (isNonStatic ? ConstDataSection : getReadOnlySection())); case SectionKind::RODataMergeStr: diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp index 40b766294f0..9dd339ed0a2 100644 --- a/lib/Target/ELFTargetAsmInfo.cpp +++ b/lib/Target/ELFTargetAsmInfo.cpp @@ -45,33 +45,6 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) SectionFlags::Writeable); } -SectionKind::Kind -ELFTargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { - SectionKind::Kind Kind = TargetAsmInfo::SectionKindForGlobal(GV); - - if (Kind != SectionKind::Data) - return Kind; - - // Decide, whether we need data.rel stuff - const GlobalVariable* GVar = dyn_cast(GV); - if (GVar->hasInitializer() && TM.getRelocationModel() != Reloc::Static) { - Constant *C = GVar->getInitializer(); - bool isConstant = GVar->isConstant(); - - // By default - all relocations in PIC mode would force symbol to be - // placed in r/w section. - switch (C->getRelocationInfo()) { - default: break; - case Constant::LocalRelocation: - return isConstant ? SectionKind::DataRelROLocal : - SectionKind::DataRelLocal; - case Constant::GlobalRelocations: - return isConstant ? SectionKind::DataRelRO : SectionKind::DataRel; - } - } - - return Kind; -} const Section* ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV, @@ -91,6 +64,8 @@ ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV, const GlobalVariable *GVar = cast(GV); switch (Kind) { default: llvm_unreachable("Unsuported section kind for global"); + case SectionKind::BSS: + return getBSSSection_(); case SectionKind::Data: case SectionKind::DataRel: return DataRelSection; @@ -100,8 +75,6 @@ ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV, return DataRelROSection; case SectionKind::DataRelROLocal: return DataRelROLocalSection; - case SectionKind::BSS: - return getBSSSection_(); case SectionKind::ROData: return getReadOnlySection(); case SectionKind::RODataMergeStr: diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 9893bf9b7aa..c52297e2caa 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -232,33 +232,72 @@ TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { return SectionKind::Text; bool isThreadLocal = GVar->isThreadLocal(); - assert(GVar && "Invalid global value for section selection"); - if (isSuitableForBSS(GVar)) { - // Variable can be easily put to BSS section. + // Variable can be easily put to BSS section. + if (isSuitableForBSS(GVar)) return isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS; - } else if (GVar->isConstant() && !isThreadLocal) { - // Now we know, that variable has initializer and it is constant. We need to - // check its initializer to decide, which section to output it into. Also - // note, there is no thread-local r/o section. - Constant *C = GVar->getInitializer(); - if (C->getRelocationInfo() != 0) { - // Decide whether it is still possible to put symbol into r/o section. - if (TM.getRelocationModel() != Reloc::Static) - return SectionKind::Data; - else - return SectionKind::ROData; - } else { - // Check, if initializer is a null-terminated string + + // If this is thread-local, put it in the general "thread_data" section. + if (isThreadLocal) + return SectionKind::ThreadData; + + Constant *C = GVar->getInitializer(); + + // If the global is marked constant, we can put it into a mergable section, + // a mergable string section, or general .data if it contains relocations. + if (GVar->isConstant()) { + // If the initializer for the global contains something that requires a + // relocation, then we may have to drop this into a wriable data section + // even though it is marked const. + switch (C->getRelocationInfo()) { + default: llvm_unreachable("unknown relocation info kind"); + case Constant::NoRelocation: + // If initializer is a null-terminated string, put it in a "cstring" + // section if the target has it. if (isConstantString(C)) return SectionKind::RODataMergeStr; - else - return SectionKind::RODataMergeConst; + + // Otherwise, just drop it into a mergable constant section. + return SectionKind::RODataMergeConst; + + case Constant::LocalRelocation: + // In static relocation model, the linker will resolve all addresses, so + // the relocation entries will actually be constants by the time the app + // starts up. + if (TM.getRelocationModel() == Reloc::Static) + return SectionKind::ROData; + + // Otherwise, the dynamic linker needs to fix it up, put it in the + // writable data.rel.local section. + return SectionKind::DataRelROLocal; + + case Constant::GlobalRelocations: + // In static relocation model, the linker will resolve all addresses, so + // the relocation entries will actually be constants by the time the app + // starts up. + if (TM.getRelocationModel() == Reloc::Static) + return SectionKind::ROData; + + // Otherwise, the dynamic linker needs to fix it up, put it in the + // writable data.rel section. + return SectionKind::DataRelRO; } } - // Variable either is not constant or thread-local - output to data section. - return isThreadLocal ? SectionKind::ThreadData : SectionKind::Data; + // Okay, this isn't a constant. If the initializer for the global is going + // to require a runtime relocation by the dynamic linker, put it into a more + // specific section to improve startup time of the app. This coalesces these + // globals together onto fewer pages, improving the locality of the dynamic + // linker. + if (TM.getRelocationModel() == Reloc::Static) + return SectionKind::Data; + + switch (C->getRelocationInfo()) { + default: llvm_unreachable("unknown relocation info kind"); + case Constant::NoRelocation: return SectionKind::Data; + case Constant::LocalRelocation: return SectionKind::DataRelLocal; + case Constant::GlobalRelocations: return SectionKind::DataRel; + } } diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp index 52b4f425927..3dc7ec4b4fa 100644 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ b/lib/Target/X86/X86TargetAsmInfo.cpp @@ -271,10 +271,14 @@ getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const { default: llvm_unreachable("Unknown section kind"); case SectionKind::Text: return ".text$linkonce"; case SectionKind::Data: + case SectionKind::DataRelLocal: + case SectionKind::DataRel: case SectionKind::BSS: case SectionKind::ThreadData: case SectionKind::ThreadBSS: return ".data$linkonce"; case SectionKind::ROData: + case SectionKind::DataRelRO: + case SectionKind::DataRelROLocal: case SectionKind::RODataMergeConst: case SectionKind::RODataMergeStr: return ".rdata$linkonce"; }