diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-07-09 13:23:37 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-07-09 13:23:37 +0000 |
commit | 01b0e24c25857cb452b21b32ec243c6bf9220a5b (patch) | |
tree | 79949ae920e23c1ea0830e30ff8b57fd7ef92703 /lib | |
parent | 4260ad3e7dc0909190a14a2d2f0098cb8ade1462 (diff) | |
download | external_llvm-01b0e24c25857cb452b21b32ec243c6bf9220a5b.zip external_llvm-01b0e24c25857cb452b21b32ec243c6bf9220a5b.tar.gz external_llvm-01b0e24c25857cb452b21b32ec243c6bf9220a5b.tar.bz2 |
Handle ELF mergeable sections
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53306 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/X86TargetAsmInfo.cpp | 65 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetAsmInfo.h | 5 |
2 files changed, 68 insertions, 2 deletions
diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp index 5e328fb..1217291 100644 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ b/lib/Target/X86/X86TargetAsmInfo.cpp @@ -341,10 +341,11 @@ X86ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { // ELF targets usually have BSS sections return getBSSSection(); case SectionKind::ROData: + return getReadOnlySection(); case SectionKind::RODataMergeStr: + return MergeableStringSection(GVar); case SectionKind::RODataMergeConst: - // FIXME: Temporary - return getReadOnlySection(); + 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 = ",\""; diff --git a/lib/Target/X86/X86TargetAsmInfo.h b/lib/Target/X86/X86TargetAsmInfo.h index 483b774..dd8d3d1 100644 --- a/lib/Target/X86/X86TargetAsmInfo.h +++ b/lib/Target/X86/X86TargetAsmInfo.h @@ -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 { |