forked from OSchip/llvm-project
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:
parent
d3bb557559
commit
708e559247
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue