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.

llvm-svn: 76993
This commit is contained in:
Chris Lattner 2009-07-24 19:15:47 +00:00
parent d3bb557559
commit 708e559247
6 changed files with 73 additions and 54 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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<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:

View File

@ -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<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 @@ ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
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 @@ 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:

View File

@ -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;
}
}

View File

@ -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";
}