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
This commit is contained in:
Chris Lattner
2009-07-24 19:15:47 +00:00
parent 49f846805e
commit b303504a56
6 changed files with 73 additions and 54 deletions

View File

@@ -37,7 +37,6 @@ namespace llvm {
/// ".tbss" gets the TLS bit set etc. /// ".tbss" gets the TLS bit set etc.
virtual unsigned getFlagsForNamedSection(const char *Section) const; virtual unsigned getFlagsForNamedSection(const char *Section) const;
SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV) const;
virtual const Section* SelectSectionForGlobal(const GlobalValue *GV, virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
SectionKind::Kind Kind) const; SectionKind::Kind Kind) const;
virtual std::string printSectionFlags(unsigned flags) const; virtual std::string printSectionFlags(unsigned flags) const;

View File

@@ -611,8 +611,7 @@ namespace llvm {
/// SectionKindForGlobal - This hook allows the target to select proper /// SectionKindForGlobal - This hook allows the target to select proper
/// section kind used for global emission. /// section kind used for global emission.
// FIXME: Eliminate this. // FIXME: Eliminate this.
virtual SectionKind::Kind SectionKind::Kind SectionKindForGlobal(const GlobalValue *GV) const;
SectionKindForGlobal(const GlobalValue *GV) const;
const std::string &getSectionFlags(unsigned Flags) const; const std::string &getSectionFlags(unsigned Flags) const;

View File

@@ -131,19 +131,24 @@ DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
bool isNonStatic = TM.getRelocationModel() != Reloc::Static; bool isNonStatic = TM.getRelocationModel() != Reloc::Static;
switch (Kind) { switch (Kind) {
case SectionKind::ThreadData:
case SectionKind::ThreadBSS:
llvm_unreachable("Darwin doesn't support TLS");
case SectionKind::Text: case SectionKind::Text:
if (isWeak) if (isWeak)
return TextCoalSection; return TextCoalSection;
return TextSection; return TextSection;
case SectionKind::Data: case SectionKind::Data:
case SectionKind::ThreadData: case SectionKind::DataRelLocal:
case SectionKind::DataRel:
case SectionKind::BSS: case SectionKind::BSS:
case SectionKind::ThreadBSS:
if (cast<GlobalVariable>(GV)->isConstant()) if (cast<GlobalVariable>(GV)->isConstant())
return isWeak ? ConstDataCoalSection : ConstDataSection; return isWeak ? ConstDataCoalSection : ConstDataSection;
return isWeak ? DataCoalSection : DataSection; return isWeak ? DataCoalSection : DataSection;
case SectionKind::ROData: case SectionKind::ROData:
case SectionKind::DataRelRO:
case SectionKind::DataRelROLocal:
return (isWeak ? ConstDataCoalSection : return (isWeak ? ConstDataCoalSection :
(isNonStatic ? ConstDataSection : getReadOnlySection())); (isNonStatic ? ConstDataSection : getReadOnlySection()));
case SectionKind::RODataMergeStr: case SectionKind::RODataMergeStr:

View File

@@ -45,33 +45,6 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
SectionFlags::Writeable); 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* const Section*
ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV, ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
@@ -91,6 +64,8 @@ ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
const GlobalVariable *GVar = cast<GlobalVariable>(GV); const GlobalVariable *GVar = cast<GlobalVariable>(GV);
switch (Kind) { switch (Kind) {
default: llvm_unreachable("Unsuported section kind for global"); default: llvm_unreachable("Unsuported section kind for global");
case SectionKind::BSS:
return getBSSSection_();
case SectionKind::Data: case SectionKind::Data:
case SectionKind::DataRel: case SectionKind::DataRel:
return DataRelSection; return DataRelSection;
@@ -100,8 +75,6 @@ ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
return DataRelROSection; return DataRelROSection;
case SectionKind::DataRelROLocal: case SectionKind::DataRelROLocal:
return DataRelROLocalSection; return DataRelROLocalSection;
case SectionKind::BSS:
return getBSSSection_();
case SectionKind::ROData: case SectionKind::ROData:
return getReadOnlySection(); return getReadOnlySection();
case SectionKind::RODataMergeStr: case SectionKind::RODataMergeStr:

View File

@@ -232,33 +232,72 @@ TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
return SectionKind::Text; return SectionKind::Text;
bool isThreadLocal = GVar->isThreadLocal(); 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; 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 // If this is thread-local, put it in the general "thread_data" section.
// check its initializer to decide, which section to output it into. Also if (isThreadLocal)
// note, there is no thread-local r/o section. return SectionKind::ThreadData;
Constant *C = GVar->getInitializer();
if (C->getRelocationInfo() != 0) { Constant *C = GVar->getInitializer();
// Decide whether it is still possible to put symbol into r/o section.
if (TM.getRelocationModel() != Reloc::Static) // If the global is marked constant, we can put it into a mergable section,
return SectionKind::Data; // a mergable string section, or general .data if it contains relocations.
else if (GVar->isConstant()) {
return SectionKind::ROData; // If the initializer for the global contains something that requires a
} else { // relocation, then we may have to drop this into a wriable data section
// Check, if initializer is a null-terminated string // 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)) if (isConstantString(C))
return SectionKind::RODataMergeStr; 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. // Okay, this isn't a constant. If the initializer for the global is going
return isThreadLocal ? SectionKind::ThreadData : SectionKind::Data; // 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;
}
} }

View File

@@ -271,10 +271,14 @@ getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
default: llvm_unreachable("Unknown section kind"); default: llvm_unreachable("Unknown section kind");
case SectionKind::Text: return ".text$linkonce"; case SectionKind::Text: return ".text$linkonce";
case SectionKind::Data: case SectionKind::Data:
case SectionKind::DataRelLocal:
case SectionKind::DataRel:
case SectionKind::BSS: case SectionKind::BSS:
case SectionKind::ThreadData: case SectionKind::ThreadData:
case SectionKind::ThreadBSS: return ".data$linkonce"; case SectionKind::ThreadBSS: return ".data$linkonce";
case SectionKind::ROData: case SectionKind::ROData:
case SectionKind::DataRelRO:
case SectionKind::DataRelROLocal:
case SectionKind::RODataMergeConst: case SectionKind::RODataMergeConst:
case SectionKind::RODataMergeStr: return ".rdata$linkonce"; case SectionKind::RODataMergeStr: return ".rdata$linkonce";
} }