mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-02 22:23:10 +00:00
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:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user