Handle ELF mergeable sections

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53306 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov 2008-07-09 13:23:37 +00:00
parent 4260ad3e7d
commit 01b0e24c25
3 changed files with 73 additions and 7 deletions

View File

@ -57,12 +57,12 @@ namespace llvm {
EntitySize = 0xFF << 24 ///< Entity size for mergeable sections
};
static inline unsigned getEntitySize(unsigned flags) {
return (flags >> 24) & 0xFF;
static inline unsigned getEntitySize(unsigned Flags) {
return (Flags >> 24) & 0xFF;
}
static inline unsigned setEntitySize(unsigned flags, unsigned size) {
return ((flags & ~EntitySize) | ((size & 0xFF) << 24));
static inline unsigned setEntitySize(unsigned Flags, unsigned Size) {
return ((Flags & ~EntitySize) | ((Size & 0xFF) << 24));
}
}

View File

@ -341,10 +341,11 @@ X86ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
// ELF targets usually have BSS sections
return getBSSSection();
case SectionKind::ROData:
case SectionKind::RODataMergeStr:
case SectionKind::RODataMergeConst:
// FIXME: Temporary
return getReadOnlySection();
case SectionKind::RODataMergeStr:
return MergeableStringSection(GVar);
case SectionKind::RODataMergeConst:
return MergeableConstSection(GVar);
case SectionKind::ThreadData:
// ELF targets usually support TLS stuff
return getTLSDataSection();
@ -358,6 +359,66 @@ X86ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
assert(0 && "Unsupported global");
}
std::string
X86ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const {
unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str());
unsigned Size = SectionFlags::getEntitySize(Flags);
// FIXME: string here is temporary, until stuff will fully land in.
if (Size)
return ".rodata.cst" + utostr(Size);
else
return getReadOnlySection();
}
std::string
X86ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const {
unsigned Flags = SectionFlagsForGlobal(GV, GV->getSection().c_str());
unsigned Size = SectionFlags::getEntitySize(Flags);
if (Size) {
// We also need alignment here
const TargetData *TD = X86TM->getTargetData();
unsigned Align = TD->getPreferredAlignment(GV);
if (Align < Size)
Align = Size;
// FIXME: string here is temporary, until stuff will fully land in.
return ".rodata.str" + utostr(Size) + ',' + utostr(Align);
} else
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);
if (Size > 32)
Size = 0;
Flags = SectionFlags::setEntitySize(Flags, Size);
}
return Flags;
}
std::string X86ELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const {
std::string Flags = ",\"";

View File

@ -20,6 +20,7 @@ namespace llvm {
// Forward declaration.
class X86TargetMachine;
class GlobalVariable;
struct X86TargetAsmInfo : public TargetAsmInfo {
explicit X86TargetAsmInfo(const X86TargetMachine &TM);
@ -47,7 +48,11 @@ namespace llvm {
bool Global) const;
virtual std::string SelectSectionForGlobal(const GlobalValue *GV) const;
virtual unsigned SectionFlagsForGlobal(const GlobalValue *GV,
const char* name) const;
virtual std::string PrintSectionFlags(unsigned flags) const;
std::string MergeableConstSection(const GlobalVariable *GV) const;
std::string MergeableStringSection(const GlobalVariable *GV) const;
};
struct X86COFFTargetAsmInfo : public X86TargetAsmInfo {