First sketch of special section objects

llvm-svn: 53320
This commit is contained in:
Anton Korobeynikov 2008-07-09 13:28:49 +00:00
parent 03dc8bf4d6
commit daee281590
4 changed files with 242 additions and 204 deletions

View File

@ -16,6 +16,7 @@
#ifndef LLVM_TARGET_ASM_INFO_H #ifndef LLVM_TARGET_ASM_INFO_H
#define LLVM_TARGET_ASM_INFO_H #define LLVM_TARGET_ASM_INFO_H
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include <string> #include <string>
@ -45,6 +46,7 @@ namespace llvm {
namespace SectionFlags { namespace SectionFlags {
enum Flags { enum Flags {
Invalid = -1UL,
None = 0, None = 0,
Code = 1 << 0, ///< Section contains code Code = 1 << 0, ///< Section contains code
Writeable = 1 << 1, ///< Section is writeable Writeable = 1 << 1, ///< Section is writeable
@ -73,40 +75,67 @@ namespace llvm {
class CallInst; class CallInst;
class GlobalValue; class GlobalValue;
class Section {
friend class TargetAsmInfo;
friend class StringMapEntry<Section>;
std::string Name;
unsigned Flags;
explicit Section(unsigned F = SectionFlags::Invalid):Flags(F) { }
public:
bool isNamed() const { return Flags & SectionFlags::Named; }
unsigned getEntitySize() const { return (Flags >> 24) & 0xFF; }
const std::string& getName() const { return Name; }
};
/// TargetAsmInfo - This class is intended to be used as a base class for asm /// TargetAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target. /// properties and features specific to the target.
class TargetAsmInfo { class TargetAsmInfo {
private:
mutable StringMap<Section> Sections;
protected: protected:
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
// Properties to be set by the target writer, used to configure asm printer. // Properties to be set by the target writer, used to configure asm printer.
// //
/// TextSection - Section directive for standard text. /// TextSection - Section directive for standard text.
/// ///
const char *TextSection; // Defaults to ".text". const char *TextSection; // Defaults to ".text".
const Section *TextSection_;
/// DataSection - Section directive for standard data. /// DataSection - Section directive for standard data.
/// ///
const char *DataSection; // Defaults to ".data". const char *DataSection; // Defaults to ".data".
const Section *DataSection_;
/// BSSSection - Section directive for uninitialized data. Null if this /// BSSSection - Section directive for uninitialized data. Null if this
/// target doesn't support a BSS section. /// target doesn't support a BSS section.
/// ///
const char *BSSSection; // Default to ".bss". const char *BSSSection; // Default to ".bss".
const Section *BSSSection_;
/// ReadOnlySection - This is the directive that is emitted to switch to a
/// read-only section for constant data (e.g. data declared const,
/// jump tables).
const char *ReadOnlySection; // Defaults to NULL
const Section *ReadOnlySection_;
/// TLSDataSection - Section directive for Thread Local data. /// TLSDataSection - Section directive for Thread Local data.
/// ///
const char *TLSDataSection;// Defaults to ".section .tdata,"awT",@progbits". const char *TLSDataSection;// Defaults to ".section .tdata,"awT",@progbits".
const Section *TLSDataSection_;
/// TLSBSSSection - Section directive for Thread Local uninitialized data. /// TLSBSSSection - Section directive for Thread Local uninitialized data.
/// Null if this target doesn't support a BSS section. /// Null if this target doesn't support a BSS section.
/// ///
const char *TLSBSSSection;// Default to ".section .tbss,"awT",@nobits". const char *TLSBSSSection;// Default to ".section .tbss,"awT",@nobits".
const Section *TLSBSSSection_;
/// ZeroFillDirective - Directive for emitting a global to the ZeroFill /// ZeroFillDirective - Directive for emitting a global to the ZeroFill
/// section on this target. Null if this target doesn't support zerofill. /// section on this target. Null if this target doesn't support zerofill.
const char *ZeroFillDirective; // Default is null. const char *ZeroFillDirective; // Default is null.
/// NonexecutableStackDirective - Directive for declaring to the /// NonexecutableStackDirective - Directive for declaring to the
/// linker and beyond that the emitted code does not require stack /// linker and beyond that the emitted code does not require stack
/// memory to be executable. /// memory to be executable.
@ -274,6 +303,7 @@ namespace llvm {
/// other null bytes) on this target. This is commonly supported as /// other null bytes) on this target. This is commonly supported as
/// ".cstring". /// ".cstring".
const char *CStringSection; // Defaults to NULL const char *CStringSection; // Defaults to NULL
const Section *CStringSection_;
/// StaticCtorsSection - This is the directive that is emitted to switch to /// StaticCtorsSection - This is the directive that is emitted to switch to
/// a section to emit the static constructor list. /// a section to emit the static constructor list.
@ -289,13 +319,11 @@ namespace llvm {
/// SixteenByteConstantSection - These are special sections where we place /// SixteenByteConstantSection - These are special sections where we place
/// 4-, 8-, and 16- byte constant literals. /// 4-, 8-, and 16- byte constant literals.
const char *FourByteConstantSection; const char *FourByteConstantSection;
const Section *FourByteConstantSection_;
const char *EightByteConstantSection; const char *EightByteConstantSection;
const Section *EightByteConstantSection_;
const char *SixteenByteConstantSection; const char *SixteenByteConstantSection;
const Section *SixteenByteConstantSection_;
/// ReadOnlySection - This is the directive that is emitted to switch to a
/// read-only section for constant data (e.g. data declared const,
/// jump tables).
const char *ReadOnlySection; // Defaults to NULL
//===--- Global Variable Emission Directives --------------------------===// //===--- Global Variable Emission Directives --------------------------===//
@ -449,6 +477,11 @@ namespace llvm {
TargetAsmInfo(); TargetAsmInfo();
virtual ~TargetAsmInfo(); virtual ~TargetAsmInfo();
const Section* getNamedSection(const char *Name,
unsigned Flags = SectionFlags::None) const;
const Section* getUnnamedSection(const char *Directive,
unsigned Flags = SectionFlags::None) const;
/// Measure the specified inline asm to determine an approximation of its /// Measure the specified inline asm to determine an approximation of its
/// length. /// length.
virtual unsigned getInlineAsmLength(const char *Str) const; virtual unsigned getInlineAsmLength(const char *Str) const;
@ -490,25 +523,46 @@ namespace llvm {
virtual std::string PrintSectionFlags(unsigned flags) const { return ""; } virtual std::string PrintSectionFlags(unsigned flags) const { return ""; }
virtual std::string SelectSectionForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const;
// Accessors. // Accessors.
// //
const char *getTextSection() const { const char *getTextSection() const {
return TextSection; return TextSection;
} }
const Section *getTextSection_() const {
return TextSection_;
}
const char *getDataSection() const { const char *getDataSection() const {
return DataSection; return DataSection;
} }
const Section *getDataSection_() const {
return DataSection_;
}
const char *getBSSSection() const { const char *getBSSSection() const {
return BSSSection; return BSSSection;
} }
const Section *getBSSSection_() const {
return BSSSection_;
}
const char *getReadOnlySection() const {
return ReadOnlySection;
}
const Section *getReadOnlySection_() const {
return ReadOnlySection_;
}
const char *getTLSDataSection() const { const char *getTLSDataSection() const {
return TLSDataSection; return TLSDataSection;
} }
const Section *getTLSDataSection_() const {
return TLSDataSection_;
}
const char *getTLSBSSSection() const { const char *getTLSBSSSection() const {
return TLSBSSSection; return TLSBSSSection;
} }
const Section *getTLSBSSSection_() const {
return TLSBSSSection_;
}
const char *getZeroFillDirective() const { const char *getZeroFillDirective() const {
return ZeroFillDirective; return ZeroFillDirective;
} }
@ -626,6 +680,9 @@ namespace llvm {
const char *getCStringSection() const { const char *getCStringSection() const {
return CStringSection; return CStringSection;
} }
const Section *getCStringSection_() const {
return CStringSection_;
}
const char *getStaticCtorsSection() const { const char *getStaticCtorsSection() const {
return StaticCtorsSection; return StaticCtorsSection;
} }
@ -635,14 +692,20 @@ namespace llvm {
const char *getFourByteConstantSection() const { const char *getFourByteConstantSection() const {
return FourByteConstantSection; return FourByteConstantSection;
} }
const Section *getFourByteConstantSection_() const {
return FourByteConstantSection_;
}
const char *getEightByteConstantSection() const { const char *getEightByteConstantSection() const {
return EightByteConstantSection; return EightByteConstantSection;
} }
const Section *getEightByteConstantSection_() const {
return EightByteConstantSection_;
}
const char *getSixteenByteConstantSection() const { const char *getSixteenByteConstantSection() const {
return SixteenByteConstantSection; return SixteenByteConstantSection;
} }
const char *getReadOnlySection() const { const Section *getSixteenByteConstantSection_() const {
return ReadOnlySection; return SixteenByteConstantSection_;
} }
const char *getGlobalDirective() const { const char *getGlobalDirective() const {
return GlobalDirective; return GlobalDirective;

View File

@ -27,10 +27,17 @@ using namespace llvm;
TargetAsmInfo::TargetAsmInfo() : TargetAsmInfo::TargetAsmInfo() :
TextSection("\t.text"), TextSection("\t.text"),
TextSection_(0),
DataSection("\t.data"), DataSection("\t.data"),
DataSection_(0),
BSSSection("\t.bss"), BSSSection("\t.bss"),
BSSSection_(0),
ReadOnlySection(0),
ReadOnlySection_(0),
TLSDataSection("\t.section .tdata,\"awT\",@progbits"), TLSDataSection("\t.section .tdata,\"awT\",@progbits"),
TLSDataSection_(0),
TLSBSSSection("\t.section .tbss,\"awT\",@nobits"), TLSBSSSection("\t.section .tbss,\"awT\",@nobits"),
TLSBSSSection_(0),
ZeroFillDirective(0), ZeroFillDirective(0),
NonexecutableStackDirective(0), NonexecutableStackDirective(0),
NeedsSet(false), NeedsSet(false),
@ -71,12 +78,15 @@ TargetAsmInfo::TargetAsmInfo() :
JumpTableDataSection("\t.section .rodata"), JumpTableDataSection("\t.section .rodata"),
JumpTableDirective(0), JumpTableDirective(0),
CStringSection(0), CStringSection(0),
CStringSection_(0),
StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"), StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"),
StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"), StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"),
FourByteConstantSection(0), FourByteConstantSection(0),
FourByteConstantSection_(0),
EightByteConstantSection(0), EightByteConstantSection(0),
EightByteConstantSection_(0),
SixteenByteConstantSection(0), SixteenByteConstantSection(0),
ReadOnlySection(0), SixteenByteConstantSection_(0),
GlobalDirective("\t.globl\t"), GlobalDirective("\t.globl\t"),
SetDirective(0), SetDirective(0),
LCOMMDirective(0), LCOMMDirective(0),
@ -112,6 +122,8 @@ TargetAsmInfo::TargetAsmInfo() :
DwarfEHFrameSection(".eh_frame"), DwarfEHFrameSection(".eh_frame"),
DwarfExceptionSection(".gcc_except_table"), DwarfExceptionSection(".gcc_except_table"),
AsmTransCBE(0) { AsmTransCBE(0) {
TextSection_ = getUnnamedSection(TextSection);
DataSection_ = getUnnamedSection(DataSection);
} }
TargetAsmInfo::~TargetAsmInfo() { TargetAsmInfo::~TargetAsmInfo() {
@ -257,51 +269,51 @@ TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
std::string std::string
TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const { TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str()); const Section* S;
std::string Name;
// FIXME: Should we use some hashing based on section name and just check
// flags?
// Select section name // Select section name
if (GV->hasSection()) { if (GV->hasSection()) {
// Honour section already set, if any // Honour section already set, if any
Name = GV->getSection(); unsigned Flags = SectionFlagsForGlobal(GV,
GV->getSection().c_str());
S = getNamedSection(GV->getSection().c_str(), Flags);
} else { } else {
// Use default section depending on the 'type' of global // Use default section depending on the 'type' of global
Name = SelectSectionForGlobal(GV); S = SelectSectionForGlobal(GV);
} }
std::string Name = S->Name;
// If section is named we need to switch into it via special '.section' // If section is named we need to switch into it via special '.section'
// directive and also append funky flags. Otherwise - section name is just // directive and also append funky flags. Otherwise - section name is just
// some magic assembler directive. // some magic assembler directive.
if (Flags & SectionFlags::Named) if (S->isNamed())
Name = getSwitchToSectionDirective() + Name + PrintSectionFlags(Flags); Name = getSwitchToSectionDirective() + Name + PrintSectionFlags(S->Flags);
return Name; return Name;
} }
// Lame default implementation. Calculate the section name for global. // Lame default implementation. Calculate the section name for global.
std::string const Section*
TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
SectionKind::Kind Kind = SectionKindForGlobal(GV); SectionKind::Kind Kind = SectionKindForGlobal(GV);
if (GV->isWeakForLinker()) if (GV->isWeakForLinker()) {
return UniqueSectionForGlobal(GV, Kind); std::string Name = UniqueSectionForGlobal(GV, Kind);
else { unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str());
return getNamedSection(Name.c_str(), Flags);
} else {
if (Kind == SectionKind::Text) if (Kind == SectionKind::Text)
return getTextSection(); return getTextSection_();
else if (Kind == SectionKind::BSS && getBSSSection()) else if (Kind == SectionKind::BSS && getBSSSection_())
return getBSSSection(); return getBSSSection_();
else if (getReadOnlySection() && else if (getReadOnlySection_() &&
(Kind == SectionKind::ROData || (Kind == SectionKind::ROData ||
Kind == SectionKind::RODataMergeConst || Kind == SectionKind::RODataMergeConst ||
Kind == SectionKind::RODataMergeStr)) Kind == SectionKind::RODataMergeStr))
return getReadOnlySection(); return getReadOnlySection_();
} }
return getDataSection(); return getDataSection_();
} }
std::string std::string
@ -326,3 +338,29 @@ TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
assert(0 && "Unknown section kind"); assert(0 && "Unknown section kind");
} }
} }
const Section*
TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags) const {
Section& S = Sections[Name];
// This is newly-created section, set it up properly.
if (S.Flags == SectionFlags::Invalid) {
S.Flags = Flags | SectionFlags::Named;
S.Name = Name;
}
return &S;
}
const Section*
TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags) const {
Section& S = Sections[Directive];
// This is newly-created section, set it up properly.
if (S.Flags == SectionFlags::Invalid) {
S.Flags = Flags & ~SectionFlags::Named;
S.Name = Directive;
}
return &S;
}

View File

@ -142,12 +142,31 @@ X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM):
ConstantPoolSection = "\t.const\n"; ConstantPoolSection = "\t.const\n";
JumpTableDataSection = "\t.const\n"; JumpTableDataSection = "\t.const\n";
CStringSection = "\t.cstring"; CStringSection = "\t.cstring";
CStringSection_ = getUnnamedSection("\t.cstring",
SectionFlags::Mergeable | SectionFlags::Strings);
FourByteConstantSection = "\t.literal4\n"; FourByteConstantSection = "\t.literal4\n";
EightByteConstantSection = "\t.literal8\n"; FourByteConstantSection_ = getUnnamedSection("\t.literal4\n",
SectionFlags::Mergeable);
EightByteConstantSection_ = getUnnamedSection("\t.literal8\n",
SectionFlags::Mergeable);
// FIXME: Why don't always use this section? // FIXME: Why don't always use this section?
if (is64Bit) if (is64Bit) {
SixteenByteConstantSection = "\t.literal16\n"; SixteenByteConstantSection = "\t.literal16\n";
SixteenByteConstantSection_ = getUnnamedSection("\t.literal16\n",
SectionFlags::Mergeable);
}
ReadOnlySection = "\t.const\n"; ReadOnlySection = "\t.const\n";
ReadOnlySection_ = getUnnamedSection("\t.const\n", SectionFlags::None);
TextCoalSection =
getUnnamedSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions",
SectionFlags::Code);
ConstDataCoalSection =
getUnnamedSection(".section __DATA,__const_coal,coalesced",
SectionFlags::None);
ConstDataSection = getUnnamedSection(".const_data", SectionFlags::None);
DataCoalSection = getUnnamedSection(".section __DATA,__datacoal_nt,coalesced",
SectionFlags::Writeable);
LCOMMDirective = "\t.lcomm\t"; LCOMMDirective = "\t.lcomm\t";
SwitchToSectionDirective = "\t.section "; SwitchToSectionDirective = "\t.section ";
StringConstantPrefix = "\1LC"; StringConstantPrefix = "\1LC";
@ -221,7 +240,7 @@ X86DarwinTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
return DW_EH_PE_absptr; return DW_EH_PE_absptr;
} }
std::string const Section*
X86DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { X86DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
SectionKind::Kind Kind = SectionKindForGlobal(GV); SectionKind::Kind Kind = SectionKindForGlobal(GV);
bool isWeak = GV->isWeakForLinker(); bool isWeak = GV->isWeakForLinker();
@ -229,29 +248,19 @@ X86DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
switch (Kind) { switch (Kind) {
case SectionKind::Text: case SectionKind::Text:
if (isWeak) if (isWeak)
return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions"; return TextCoalSection;
else else
return getTextSection(); return getTextSection_();
case SectionKind::Data: case SectionKind::Data:
case SectionKind::ThreadData: case SectionKind::ThreadData:
case SectionKind::BSS: case SectionKind::BSS:
case SectionKind::ThreadBSS: case SectionKind::ThreadBSS:
if (cast<GlobalVariable>(GV)->isConstant()) { if (cast<GlobalVariable>(GV)->isConstant())
if (isWeak) return (isWeak ? ConstDataCoalSection : ConstDataSection);
return ".section __DATA,__const_coal,coalesced";
else
return ".const_data";
} else {
if (isWeak)
return ".section __DATA,__datacoal_nt,coalesced";
else
return getDataSection();
}
case SectionKind::ROData:
if (isWeak)
return ".section __DATA,__const_coal,coalesced";
else else
return getReadOnlySection(); return (isWeak ? DataCoalSection : getDataSection_());
case SectionKind::ROData:
return (isWeak ? ConstDataCoalSection : getReadOnlySection_());
case SectionKind::RODataMergeStr: case SectionKind::RODataMergeStr:
return MergeableStringSection(cast<GlobalVariable>(GV)); return MergeableStringSection(cast<GlobalVariable>(GV));
case SectionKind::RODataMergeConst: case SectionKind::RODataMergeConst:
@ -263,34 +272,37 @@ X86DarwinTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
// FIXME: Do we have any extra special weird cases? // FIXME: Do we have any extra special weird cases?
} }
std::string const Section*
X86DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { X86DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str()); const TargetData *TD = X86TM->getTargetData();
unsigned Size = SectionFlags::getEntitySize(Flags); Constant *C = cast<GlobalVariable>(GV)->getInitializer();
const Type *Type = cast<ConstantArray>(C)->getType()->getElementType();
unsigned Size = TD->getABITypeSize(Type);
if (Size) { if (Size) {
const TargetData *TD = X86TM->getTargetData(); const TargetData *TD = X86TM->getTargetData();
unsigned Align = TD->getPreferredAlignment(GV); unsigned Align = TD->getPreferredAlignment(GV);
if (Align <= 32) if (Align <= 32)
return getCStringSection(); return getCStringSection_();
} }
return getReadOnlySection(); return getReadOnlySection_();
} }
std::string const Section*
X86DarwinTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { X86DarwinTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const {
unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str()); const TargetData *TD = X86TM->getTargetData();
unsigned Size = SectionFlags::getEntitySize(Flags); Constant *C = cast<GlobalVariable>(GV)->getInitializer();
unsigned Size = TD->getABITypeSize(C->getType());
if (Size == 4) if (Size == 4)
return FourByteConstantSection; return FourByteConstantSection_;
else if (Size == 8) else if (Size == 8)
return EightByteConstantSection; return EightByteConstantSection_;
else if (Size == 16 && X86TM->getSubtarget<X86Subtarget>().is64Bit()) else if (Size == 16 && X86TM->getSubtarget<X86Subtarget>().is64Bit())
return SixteenByteConstantSection; return SixteenByteConstantSection_;
return getReadOnlySection(); return getReadOnlySection_();
} }
std::string std::string
@ -300,44 +312,20 @@ X86DarwinTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
return ""; return "";
} }
unsigned
X86DarwinTargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
const char* name) const {
unsigned Flags =
TargetAsmInfo::SectionFlagsForGlobal(GV,
GV->getSection().c_str());
// If there was decision to put stuff into mergeable section - calculate
// entity size
if (Flags & SectionFlags::Mergeable) {
const TargetData *TD = X86TM->getTargetData();
Constant *C = cast<GlobalVariable>(GV)->getInitializer();
const Type *Type;
if (Flags & SectionFlags::Strings) {
const ConstantArray *CVA = cast<ConstantArray>(C);
Type = CVA->getType()->getElementType();
} else
Type = C->getType();
unsigned Size = TD->getABITypeSize(Type);
if (Size > 16 ||
!(Flags & SectionFlags::Strings ||
(Size == 4 || Size == 8 || Size == 16))) {
// Not suitable for mergeable
Size = 0;
Flags &= ~SectionFlags::Mergeable;
}
Flags = SectionFlags::setEntitySize(Flags, Size);
}
return Flags;
}
X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM): X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM):
X86TargetAsmInfo(TM) { X86TargetAsmInfo(TM) {
bool is64Bit = X86TM->getSubtarget<X86Subtarget>().is64Bit(); bool is64Bit = X86TM->getSubtarget<X86Subtarget>().is64Bit();
TextSection_ = getUnnamedSection("\t.text", SectionFlags::Code);
DataSection_ = getUnnamedSection("\t.data", SectionFlags::Writeable);
BSSSection_ = getUnnamedSection("\t.bss",
SectionFlags::Writeable | SectionFlags::BSS);
ReadOnlySection_ = getUnnamedSection("\t.rodata", SectionFlags::None);
TLSDataSection_ = getNamedSection("\t.tdata",
SectionFlags::Writeable | SectionFlags::TLS);
TLSBSSSection_ = getNamedSection("\t.tbss",
SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS);
ReadOnlySection = ".rodata"; ReadOnlySection = ".rodata";
FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4"; FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4";
EightByteConstantSection = "\t.section\t.rodata.cst8,\"aM\",@progbits,8"; EightByteConstantSection = "\t.section\t.rodata.cst8,\"aM\",@progbits,8";
@ -417,9 +405,9 @@ X86ELFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
} }
} }
std::string const Section*
X86ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { X86ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
SectionKind::Kind kind = SectionKindForGlobal(GV); SectionKind::Kind Kind = SectionKindForGlobal(GV);
if (const Function *F = dyn_cast<Function>(GV)) { if (const Function *F = dyn_cast<Function>(GV)) {
switch (F->getLinkage()) { switch (F->getLinkage()) {
@ -427,32 +415,36 @@ X86ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
case Function::InternalLinkage: case Function::InternalLinkage:
case Function::DLLExportLinkage: case Function::DLLExportLinkage:
case Function::ExternalLinkage: case Function::ExternalLinkage:
return getTextSection(); return getTextSection_();
case Function::WeakLinkage: case Function::WeakLinkage:
case Function::LinkOnceLinkage: case Function::LinkOnceLinkage:
return UniqueSectionForGlobal(F, kind); std::string Name = UniqueSectionForGlobal(GV, Kind);
unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str());
return getNamedSection(Name.c_str(), Flags);
} }
} else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { } else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
if (GVar->isWeakForLinker()) if (GVar->isWeakForLinker()) {
return UniqueSectionForGlobal(GVar, kind); std::string Name = UniqueSectionForGlobal(GVar, Kind);
else { unsigned Flags = SectionFlagsForGlobal(GVar, Name.c_str());
switch (kind) { return getNamedSection(Name.c_str(), Flags);
} else {
switch (Kind) {
case SectionKind::Data: case SectionKind::Data:
return getDataSection(); return getDataSection_();
case SectionKind::BSS: case SectionKind::BSS:
// ELF targets usually have BSS sections // ELF targets usually have BSS sections
return getBSSSection(); return getBSSSection_();
case SectionKind::ROData: case SectionKind::ROData:
return getReadOnlySection(); return getReadOnlySection_();
case SectionKind::RODataMergeStr: case SectionKind::RODataMergeStr:
return MergeableStringSection(GVar); return MergeableStringSection(GVar);
case SectionKind::RODataMergeConst: case SectionKind::RODataMergeConst:
return MergeableConstSection(GVar); return MergeableConstSection(GVar);
case SectionKind::ThreadData: case SectionKind::ThreadData:
// ELF targets usually support TLS stuff // ELF targets usually support TLS stuff
return getTLSDataSection(); return getTLSDataSection_();
case SectionKind::ThreadBSS: case SectionKind::ThreadBSS:
return getTLSBSSSection(); return getTLSBSSSection_();
default: default:
assert(0 && "Unsuported section kind for global"); assert(0 && "Unsuported section kind for global");
} }
@ -461,87 +453,52 @@ X86ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
assert(0 && "Unsupported global"); assert(0 && "Unsupported global");
} }
std::string const Section*
X86ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { X86ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const {
unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str()); const TargetData *TD = X86TM->getTargetData();
unsigned Size = SectionFlags::getEntitySize(Flags); Constant *C = cast<GlobalVariable>(GV)->getInitializer();
const Type *Type = C->getType();
// FIXME: string here is temporary, until stuff will fully land in. // FIXME: string here is temporary, until stuff will fully land in.
// We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's
// currently directly used by asmprinter. // currently directly used by asmprinter.
if (Size == 4 || Size == 8 || Size == 16) unsigned Size = TD->getABITypeSize(Type);
return ".rodata.cst" + utostr(Size); if (Size == 4 || Size == 8 || Size == 16) {
std::string Name = ".rodata.cst" + utostr(Size);
return getReadOnlySection(); return getNamedSection(Name.c_str(),
SectionFlags::setEntitySize(SectionFlags::Mergeable,
Size));
}
return getReadOnlySection_();
} }
std::string const Section*
X86ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { X86ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str()); const TargetData *TD = X86TM->getTargetData();
unsigned Size = SectionFlags::getEntitySize(Flags); Constant *C = cast<GlobalVariable>(GV)->getInitializer();
const ConstantArray *CVA = cast<ConstantArray>(C);
const Type *Type = CVA->getType()->getElementType();
if (Size) { unsigned Size = TD->getABITypeSize(Type);
if (Size <= 16) {
// We also need alignment here // We also need alignment here
const TargetData *TD = X86TM->getTargetData(); const TargetData *TD = X86TM->getTargetData();
unsigned Align = TD->getPreferredAlignment(GV); unsigned Align = TD->getPreferredAlignment(GV);
if (Align < Size) if (Align < Size)
Align = Size; Align = Size;
return getCStringSection() + utostr(Size) + '.' + utostr(Align); std::string Name = getCStringSection() + utostr(Size) + '.' + utostr(Align);
unsigned Flags = SectionFlags::setEntitySize(SectionFlags::Mergeable |
SectionFlags::Strings,
Size);
return getNamedSection(Name.c_str(), Flags);
} }
return getReadOnlySection(); return getReadOnlySection_();
} }
unsigned
X86ELFTargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
const char* name) const {
unsigned Flags =
TargetAsmInfo::SectionFlagsForGlobal(GV,
GV->getSection().c_str());
// If there was decision to put stuff into mergeable section - calculate
// entity size
if (Flags & SectionFlags::Mergeable) {
const TargetData *TD = X86TM->getTargetData();
Constant *C = cast<GlobalVariable>(GV)->getInitializer();
const Type *Type;
if (Flags & SectionFlags::Strings) {
const ConstantArray *CVA = cast<ConstantArray>(C);
Type = CVA->getType()->getElementType();
} else
Type = C->getType();
unsigned Size = TD->getABITypeSize(Type);
// FIXME: size check here ugly, and will hopefully have gone, when we will
// have sane interface for attaching flags to sections.
if (Size > 16 ||
!(Flags & SectionFlags::Strings ||
(Size == 4 || Size == 8 || Size == 16))) {
// Not suitable for mergeable
Size = 0;
Flags &= ~SectionFlags::Mergeable;
}
Flags = SectionFlags::setEntitySize(Flags, Size);
}
// FIXME: This is hacky and will be removed when switching from std::string
// sections into 'general' ones
// Mark section as named, when needed (so, we we will need .section directive
// to switch into it).
unsigned TypeFlags = Flags & SectionFlags::TypeFlags;
if (!TypeFlags /* Read-only section */ ||
(TypeFlags & (SectionFlags::Mergeable |
SectionFlags::TLS |
SectionFlags::Linkonce)))
Flags |= SectionFlags::Named;
return Flags;
}
std::string X86ELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { std::string X86ELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const {
std::string Flags = ",\""; std::string Flags = ",\"";
@ -663,25 +620,6 @@ X86COFFTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
} }
} }
unsigned
X86COFFTargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
const char* name) const {
unsigned Flags =
TargetAsmInfo::SectionFlagsForGlobal(GV,
GV->getSection().c_str());
// Mark section as named, when needed (so, we we will need .section directive
// to switch into it).
unsigned TypeFlags = Flags & SectionFlags::TypeFlags;
if (!TypeFlags /* Read-only section */ ||
(TypeFlags & (SectionFlags::Mergeable |
SectionFlags::TLS |
SectionFlags::Linkonce)))
Flags |= SectionFlags::Named;
return Flags;
}
std::string X86COFFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { std::string X86COFFTargetAsmInfo::PrintSectionFlags(unsigned flags) const {
std::string Flags = ",\""; std::string Flags = ",\"";

View File

@ -34,16 +34,19 @@ namespace llvm {
}; };
struct X86DarwinTargetAsmInfo : public X86TargetAsmInfo { struct X86DarwinTargetAsmInfo : public X86TargetAsmInfo {
const Section* TextCoalSection;
const Section* ConstDataCoalSection;
const Section* ConstDataSection;
const Section* DataCoalSection;
explicit X86DarwinTargetAsmInfo(const X86TargetMachine &TM); explicit X86DarwinTargetAsmInfo(const X86TargetMachine &TM);
virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
bool Global) const; bool Global) const;
virtual std::string SelectSectionForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const;
virtual unsigned SectionFlagsForGlobal(const GlobalValue *GV,
const char* name) const;
virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
SectionKind::Kind kind) const; SectionKind::Kind kind) const;
std::string MergeableConstSection(const GlobalVariable *GV) const; const Section* MergeableConstSection(const GlobalVariable *GV) const;
std::string MergeableStringSection(const GlobalVariable *GV) const; const Section* MergeableStringSection(const GlobalVariable *GV) const;
}; };
struct X86ELFTargetAsmInfo : public X86TargetAsmInfo { struct X86ELFTargetAsmInfo : public X86TargetAsmInfo {
@ -51,20 +54,16 @@ namespace llvm {
virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
bool Global) const; bool Global) const;
virtual std::string SelectSectionForGlobal(const GlobalValue *GV) const; virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const;
virtual unsigned SectionFlagsForGlobal(const GlobalValue *GV,
const char* name) const;
virtual std::string PrintSectionFlags(unsigned flags) const; virtual std::string PrintSectionFlags(unsigned flags) const;
std::string MergeableConstSection(const GlobalVariable *GV) const; const Section* MergeableConstSection(const GlobalVariable *GV) const;
std::string MergeableStringSection(const GlobalVariable *GV) const; const Section* MergeableStringSection(const GlobalVariable *GV) const ;
}; };
struct X86COFFTargetAsmInfo : public X86TargetAsmInfo { struct X86COFFTargetAsmInfo : public X86TargetAsmInfo {
explicit X86COFFTargetAsmInfo(const X86TargetMachine &TM); explicit X86COFFTargetAsmInfo(const X86TargetMachine &TM);
virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason, virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
bool Global) const; bool Global) const;
virtual unsigned SectionFlagsForGlobal(const GlobalValue *GV,
const char* name) const;
virtual std::string UniqueSectionForGlobal(const GlobalValue* GV, virtual std::string UniqueSectionForGlobal(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;