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 63e3acd..54220e7 100644
--- a/include/llvm/Target/ELFTargetAsmInfo.h
+++ b/include/llvm/Target/ELFTargetAsmInfo.h
@@ -37,7 +37,6 @@
/// ".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 a349116..322c57f 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -611,8 +611,7 @@
/// 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 27714f2..2d3c5ff 100644
--- a/lib/Target/DarwinTargetAsmInfo.cpp
+++ b/lib/Target/DarwinTargetAsmInfo.cpp
@@ -131,19 +131,24 @@
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<GlobalVariable>(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 40b7662..9dd339e 100644
--- a/lib/Target/ELFTargetAsmInfo.cpp
+++ b/lib/Target/ELFTargetAsmInfo.cpp
@@ -45,33 +45,6 @@
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<GlobalVariable>(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 @@
const GlobalVariable *GVar = cast<GlobalVariable>(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 @@
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 9893bf9..c52297e 100644
--- a/lib/Target/TargetAsmInfo.cpp
+++ b/lib/Target/TargetAsmInfo.cpp
@@ -232,33 +232,72 @@
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 52b4f42..3dc7ec4 100644
--- a/lib/Target/X86/X86TargetAsmInfo.cpp
+++ b/lib/Target/X86/X86TargetAsmInfo.cpp
@@ -271,10 +271,14 @@
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";
}