this is (unfortunately) several changes mixed together:

1. Spell SectionFlags::Writeable as "Writable".
2. Add predicates for deriving SectionFlags from SectionKinds.
3. Sink ELF-specific getSectionPrefixForUniqueGlobal impl into
   ELFTargetAsmInfo.
4. Fix SectionFlagsForGlobal to know that BSS/ThreadBSS has the
   BSS bit set (the real fix for PR4619).
5. Fix isSuitableForBSS to not put globals with explicit sections
   set in BSS (which was the reason #4 wasn't fixed earlier).
6. Remove my previous hack for PR4619.

llvm-svn: 77085
This commit is contained in:
Chris Lattner 2009-07-25 18:57:34 +00:00
parent 7b5e51091e
commit 60f3b73e11
14 changed files with 100 additions and 89 deletions

View File

@ -43,12 +43,6 @@ namespace llvm {
virtual const Section *
getSectionForMergableConstant(uint64_t Size, unsigned ReloInfo) const;
virtual const char *
getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
// Darwin doesn't use uniqued sections for weak symbols.
return 0;
}
private:
const Section* MergeableStringSection(const GlobalVariable *GV) const;
};

View File

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

View File

@ -62,13 +62,35 @@ namespace llvm {
K == SectionKind::RODataMergeConst ||
K == SectionKind::RODataMergeStr);
}
static inline bool isBSS(Kind K) {
return K == BSS || K == ThreadBSS;
}
static inline bool isTLS(Kind K) {
return K == ThreadData || K == ThreadBSS;
}
static inline bool isCode(Kind K) {
return K == Text;
}
static inline bool isWritable(Kind K) {
return isTLS(K) ||
K == SectionKind::Data ||
K == SectionKind::DataRel ||
K == SectionKind::DataRelLocal ||
K == SectionKind::DataRelRO ||
K == SectionKind::DataRelROLocal ||
K == SectionKind::BSS;
}
}
namespace SectionFlags {
const unsigned Invalid = -1U;
const unsigned None = 0;
const unsigned Code = 1 << 0; ///< Section contains code
const unsigned Writeable = 1 << 1; ///< Section is writeable
const unsigned Writable = 1 << 1; ///< Section is writable
const unsigned BSS = 1 << 2; ///< Section contains only zeroes
const unsigned Mergeable = 1 << 3; ///< Section contains mergeable data
const unsigned Strings = 1 << 4; ///< Section contains C-type strings
@ -582,7 +604,9 @@ namespace llvm {
/// global. This is important for globals that need to be merged across
/// translation units.
virtual const char *
getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const;
getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
return 0;
}
/// getFlagsForNamedSection - If this target wants to be able to infer
/// section flags based on the name of the section specified for a global

View File

@ -222,7 +222,7 @@ unsigned ELFWriter::getElfSectionFlags(unsigned Flags) {
if (Flags & SectionFlags::Code)
ElfSectionFlags |= ELFSection::SHF_EXECINSTR;
if (Flags & SectionFlags::Writeable)
if (Flags & SectionFlags::Writable)
ElfSectionFlags |= ELFSection::SHF_WRITE;
if (Flags & SectionFlags::Mergeable)
ElfSectionFlags |= ELFSection::SHF_MERGE;

View File

@ -36,7 +36,7 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) :
// BSS section needs to be emitted as ".section"
BSSSection = "\t.section\t.bss";
BSSSection_ = getUnnamedSection("\t.section\t.bss",
SectionFlags::Writeable | SectionFlags::BSS,
SectionFlags::Writable | SectionFlags::BSS,
true);
SupportsDebugInformation = true;

View File

@ -50,7 +50,7 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM)
SectionFlags::None);
ConstDataSection = getUnnamedSection(".const_data", SectionFlags::None);
DataCoalSection = getNamedSection("\t__DATA,__datacoal_nt,coalesced",
SectionFlags::Writeable);
SectionFlags::Writable);
// Common settings for all Darwin targets.
@ -127,6 +127,7 @@ bool DarwinTargetAsmInfo::emitUsedDirectiveFor(const GlobalValue* GV,
const Section*
DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
SectionKind::Kind Kind) const {
// FIXME: Use sectionflags:linkonce instead of isWeakForLinker() here.
bool isWeak = GV->isWeakForLinker();
bool isNonStatic = TM.getRelocationModel() != Reloc::Static;

View File

@ -29,20 +29,20 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
: TargetAsmInfo(TM) {
BSSSection_ = getUnnamedSection("\t.bss",
SectionFlags::Writeable | SectionFlags::BSS);
SectionFlags::Writable | SectionFlags::BSS);
ReadOnlySection = getNamedSection("\t.rodata", SectionFlags::None);
TLSDataSection = getNamedSection("\t.tdata",
SectionFlags::Writeable | SectionFlags::TLS);
SectionFlags::Writable | SectionFlags::TLS);
TLSBSSSection = getNamedSection("\t.tbss",
SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS);
SectionFlags::Writable | SectionFlags::TLS | SectionFlags::BSS);
DataRelSection = getNamedSection("\t.data.rel", SectionFlags::Writeable);
DataRelSection = getNamedSection("\t.data.rel", SectionFlags::Writable);
DataRelLocalSection = getNamedSection("\t.data.rel.local",
SectionFlags::Writeable);
SectionFlags::Writable);
DataRelROSection = getNamedSection("\t.data.rel.ro",
SectionFlags::Writeable);
SectionFlags::Writable);
DataRelROLocalSection = getNamedSection("\t.data.rel.ro.local",
SectionFlags::Writeable);
SectionFlags::Writable);
}
@ -145,6 +145,28 @@ unsigned ELFTargetAsmInfo::getFlagsForNamedSection(const char *Name) const {
}
const char *
ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const{
switch (Kind) {
default: llvm_unreachable("Unknown section kind");
case SectionKind::Text: return ".gnu.linkonce.t.";
case SectionKind::Data: return ".gnu.linkonce.d.";
case SectionKind::DataRel: return ".gnu.linkonce.d.rel.";
case SectionKind::DataRelLocal: return ".gnu.linkonce.d.rel.local.";
case SectionKind::DataRelRO: return ".gnu.linkonce.d.rel.ro.";
case SectionKind::DataRelROLocal: return ".gnu.linkonce.d.rel.ro.local.";
case SectionKind::BSS: return ".gnu.linkonce.b.";
case SectionKind::ROData:
case SectionKind::RODataMergeConst:
case SectionKind::RODataMergeStr: return ".gnu.linkonce.r.";
case SectionKind::ThreadData: return ".gnu.linkonce.td.";
case SectionKind::ThreadBSS: return ".gnu.linkonce.tb.";
}
}
const Section*
ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
const TargetData *TD = TM.getTargetData();
@ -177,7 +199,7 @@ std::string ELFTargetAsmInfo::printSectionFlags(unsigned flags) const {
Flags += 'a';
if (flags & SectionFlags::Code)
Flags += 'x';
if (flags & SectionFlags::Writeable)
if (flags & SectionFlags::Writable)
Flags += 'w';
if (flags & SectionFlags::Mergeable)
Flags += 'M';

View File

@ -292,7 +292,7 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
const char *SectionName = PAN::getFrameSectionName(CurrentFnName).c_str();
const Section *fPDataSection = TAI->getNamedSection(SectionName,
SectionFlags::Writeable);
SectionFlags::Writable);
SwitchToSection(fPDataSection);
// Emit function frame label

View File

@ -38,9 +38,9 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
AsciiDirective = " dt ";
AscizDirective = NULL;
BSSSection_ = getNamedSection("udata.# UDATA",
SectionFlags::Writeable | SectionFlags::BSS);
SectionFlags::Writable | SectionFlags::BSS);
ReadOnlySection = getNamedSection("romdata.# ROMDATA", SectionFlags::None);
DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable);
DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writable);
SwitchToSectionDirective = "";
// Need because otherwise a .text symbol is emitted by DwarfWriter
// in BeginModule, and gpasm cribbs for that .text symbol.

View File

@ -75,7 +75,7 @@ PPCLinuxTargetAsmInfo::PPCLinuxTargetAsmInfo(const PPCTargetMachine &TM) :
// PPC/Linux normally uses named section for BSS.
BSSSection_ = getNamedSection("\t.bss",
SectionFlags::Writeable | SectionFlags::BSS,
SectionFlags::Writable | SectionFlags::BSS,
/* Override */ true);
// Debug Information

View File

@ -28,7 +28,7 @@ SparcELFTargetAsmInfo::SparcELFTargetAsmInfo(const TargetMachine &TM):
// Sparc normally uses named section for BSS.
BSSSection_ = getNamedSection("\t.bss",
SectionFlags::Writeable | SectionFlags::BSS,
SectionFlags::Writable | SectionFlags::BSS,
/* Override */ true);
}
@ -41,7 +41,7 @@ std::string SparcELFTargetAsmInfo::printSectionFlags(unsigned flags) const {
Flags += ",#alloc";
if (flags & SectionFlags::Code)
Flags += ",#execinstr";
if (flags & SectionFlags::Writeable)
if (flags & SectionFlags::Writable)
Flags += ",#write";
if (flags & SectionFlags::TLS)
Flags += ",#tls";

View File

@ -122,7 +122,7 @@ TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm) : TM(tm) {
DwarfExceptionSection = ".gcc_except_table";
AsmTransCBE = 0;
TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable);
DataSection = getUnnamedSection("\t.data", SectionFlags::Writable);
}
TargetAsmInfo::~TargetAsmInfo() {
@ -160,9 +160,22 @@ unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
}
static bool isSuitableForBSS(const GlobalVariable *GV) {
// Leave constant zeros in readonly constant sections, so they can be shared
Constant *C = GV->getInitializer();
return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
// Must have zero initializer.
if (!C->isNullValue())
return false;
// Leave constant zeros in readonly constant sections, so they can be shared.
if (GV->isConstant())
return false;
// If the global has an explicit section specified, don't put it in BSS.
if (!GV->getSection().empty())
return false;
// Otherwise, put it in BSS unless the target really doesn't want us to.
return !NoZerosInBSS;
}
static bool isConstantString(const Constant *C) {
@ -183,36 +196,18 @@ static bool isConstantString(const Constant *C) {
static unsigned SectionFlagsForGlobal(const GlobalValue *GV,
SectionKind::Kind Kind) {
// Decode flags from global and section kind.
unsigned Flags = SectionFlags::None;
// Decode flags from global itself.
switch (Kind) {
case SectionKind::Text:
Flags |= SectionFlags::Code;
break;
case SectionKind::ThreadData:
case SectionKind::ThreadBSS:
Flags |= SectionFlags::TLS;
// FALLS THROUGH
case SectionKind::Data:
case SectionKind::DataRel:
case SectionKind::DataRelLocal:
case SectionKind::DataRelRO:
case SectionKind::DataRelROLocal:
case SectionKind::BSS:
Flags |= SectionFlags::Writeable;
break;
case SectionKind::ROData:
case SectionKind::RODataMergeStr:
case SectionKind::RODataMergeConst:
// No additional flags here
break;
default:
llvm_unreachable("Unexpected section kind!");
}
if (GV->isWeakForLinker())
Flags |= SectionFlags::Linkonce;
if (SectionKind::isBSS(Kind))
Flags |= SectionFlags::BSS;
if (SectionKind::isTLS(Kind))
Flags |= SectionFlags::TLS;
if (SectionKind::isCode(Kind))
Flags |= SectionFlags::Code;
if (SectionKind::isWritable(Kind))
Flags |= SectionFlags::Writable;
return Flags;
}
@ -331,11 +326,6 @@ const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
// FIXME: Use mangler interface (PR4584).
std::string Name = Prefix+GV->getNameStr();
// Pick up the flags for the uniquing section.
// FIXME: HACK.
Flags |= getFlagsForNamedSection(Name.c_str());
return getNamedSection(Name.c_str(), Flags);
}
}
@ -348,10 +338,10 @@ const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
const Section*
TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
SectionKind::Kind Kind) const {
if (Kind == SectionKind::Text)
if (SectionKind::isCode(Kind))
return getTextSection();
if (Kind == SectionKind::BSS)
if (SectionKind::isBSS(SectionKind::BSS))
if (const Section *S = getBSSSection_())
return S;
@ -374,27 +364,6 @@ TargetAsmInfo::getSectionForMergableConstant(uint64_t Size,
}
const char *
TargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
switch (Kind) {
default: llvm_unreachable("Unknown section kind");
case SectionKind::Text: return ".gnu.linkonce.t.";
case SectionKind::Data: return ".gnu.linkonce.d.";
case SectionKind::DataRel: return ".gnu.linkonce.d.rel.";
case SectionKind::DataRelLocal: return ".gnu.linkonce.d.rel.local.";
case SectionKind::DataRelRO: return ".gnu.linkonce.d.rel.ro.";
case SectionKind::DataRelROLocal: return ".gnu.linkonce.d.rel.ro.local.";
case SectionKind::BSS: return ".gnu.linkonce.b.";
case SectionKind::ROData:
case SectionKind::RODataMergeConst:
case SectionKind::RODataMergeStr: return ".gnu.linkonce.r.";
case SectionKind::ThreadData: return ".gnu.linkonce.td.";
case SectionKind::ThreadBSS: return ".gnu.linkonce.tb.";
}
}
const Section *TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags,
bool Override) const {
Section &S = Sections[Name];

View File

@ -282,7 +282,6 @@ getSectionPrefixForUniqueGlobal(SectionKind::Kind Kind) const {
case SectionKind::RODataMergeConst:
case SectionKind::RODataMergeStr: return ".rdata$linkonce";
}
return NULL;
}
std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const {
@ -290,7 +289,7 @@ std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const {
if (flags & SectionFlags::Code)
Flags += 'x';
if (flags & SectionFlags::Writeable)
if (flags & SectionFlags::Writable)
Flags += 'w';
Flags += "\"";
@ -322,7 +321,7 @@ X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM):
AlignmentIsInBytes = true;
TextSection = getUnnamedSection("_text", SectionFlags::Code);
DataSection = getUnnamedSection("_data", SectionFlags::Writeable);
DataSection = getUnnamedSection("_data", SectionFlags::Writable);
JumpTableDataSection = NULL;
SwitchToSectionDirective = "";

View File

@ -25,8 +25,8 @@ XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM)
: ELFTargetAsmInfo(TM) {
SupportsDebugInformation = true;
TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
DataSection = getNamedSection("\t.dp.data", SectionFlags::Writeable);
BSSSection_ = getNamedSection("\t.dp.bss", SectionFlags::Writeable |
DataSection = getNamedSection("\t.dp.data", SectionFlags::Writable);
BSSSection_ = getNamedSection("\t.dp.bss", SectionFlags::Writable |
SectionFlags::BSS);
// TLS globals are lowered in the backend to arrays indexed by the current
@ -36,7 +36,7 @@ XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM)
TLSBSSSection = BSSSection_;
if (TM.getSubtargetImpl()->isXS1A())
ReadOnlySection = getNamedSection("\t.dp.rodata", SectionFlags::Writeable);
ReadOnlySection = getNamedSection("\t.dp.rodata", SectionFlags::Writable);
else
ReadOnlySection = getNamedSection("\t.cp.rodata", SectionFlags::None);
Data16bitsDirective = "\t.short\t";