Sink getSectionPrefixForUniqueGlobal down into the TAI

implementations that need it, rearrange ELFTAI.

llvm-svn: 77236
This commit is contained in:
Chris Lattner 2009-07-27 19:14:14 +00:00
parent 067c407c48
commit e7cb8f7987
6 changed files with 155 additions and 126 deletions

View File

@ -17,12 +17,12 @@ namespace llvm {
protected:
explicit COFFTargetAsmInfo(const TargetMachine &TM);
public:
virtual const char *
getSectionPrefixForUniqueGlobal(SectionKind kind) const;
virtual void getSectionFlagsAsString(SectionKind Kind,
SmallVectorImpl<char> &Str) const;
virtual const Section *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind) const;
};
}

View File

@ -33,8 +33,6 @@ namespace llvm {
void getSectionFlagsAsString(SectionKind Kind,
SmallVectorImpl<char> &Str) const;
const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) const;
virtual const Section* SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind) const;

View File

@ -144,6 +144,9 @@ namespace llvm {
bool ExplicitSection : 1;
public:
// FIXME: REMOVE.
Kind getKind() const { return K; }
bool isWeak() const { return Weak; }
bool hasExplicitSection() const { return ExplicitSection; }
@ -669,15 +672,6 @@ namespace llvm {
virtual const Section *getSectionForMergeableConstant(SectionKind Kind)const;
/// getSectionPrefixForUniqueGlobal - Return a string that we should prepend
/// onto a global's name in order to get the unique section name for the
/// global. This is important for globals that need to be merged across
/// translation units.
virtual const char *
getSectionPrefixForUniqueGlobal(SectionKind Kind) const {
return 0;
}
/// getKindForNamedSection - If this target wants to be able to override
/// section flags based on the name of the section specified for a global
/// variable, it can implement this. This is used on ELF systems so that

View File

@ -53,15 +53,6 @@ COFFTargetAsmInfo::COFFTargetAsmInfo(const TargetMachine &TM)
DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"dr\"";
}
const char *COFFTargetAsmInfo::
getSectionPrefixForUniqueGlobal(SectionKind Kind) const {
if (Kind.isText())
return ".text$linkonce";
if (Kind.isWriteable())
return ".data$linkonce";
return ".rdata$linkonce";
}
void COFFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
SmallVectorImpl<char> &Str) const {
// FIXME: Inefficient.
@ -74,3 +65,45 @@ void COFFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
Str.append(Res.begin(), Res.end());
}
//===----------------------------------------------------------------------===//
// Move to AsmPrinter (mangler access).
//===----------------------------------------------------------------------===//
#include "llvm/GlobalVariable.h"
static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
if (Kind.isText())
return ".text$linkonce";
if (Kind.isWriteable())
return ".data$linkonce";
return ".rdata$linkonce";
}
const Section *
COFFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind) const {
assert(!Kind.isThreadLocal() && "Doesn't support TLS");
// If this global is linkonce/weak and the target handles this by emitting it
// into a 'uniqued' section name, create and return the section now.
if (Kind.isWeak()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
// FIXME: Use mangler interface (PR4584).
std::string Name = Prefix+GV->getNameStr();
return getOrCreateSection(Name.c_str(), false, Kind.getKind());
}
if (Kind.isText())
return getTextSection();
if (Kind.isBSS())
if (const Section *S = getBSSSection_())
return S;
if (Kind.isReadOnly())
if (const Section *S = getReadOnlySection())
return S;
return getDataSection();
}

View File

@ -12,16 +12,8 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/ELFTargetAsmInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
@ -53,10 +45,131 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM)
SectionKind::MergeableConst16);
}
/// getFlagsForNamedSection - If this target wants to be able to infer
/// section flags based on the name of the section specified for a global
/// variable, it can implement this.
SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name,
SectionKind::Kind K) const {
if (Name[0] != '.') return K;
// Some lame default implementation based on some magic section names.
if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
return SectionKind::BSS;
if (strcmp(Name, ".tdata") == 0 ||
strncmp(Name, ".tdata.", 7) == 0 ||
strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
return SectionKind::ThreadData;
if (strcmp(Name, ".tbss") == 0 ||
strncmp(Name, ".tbss.", 6) == 0 ||
strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
return SectionKind::ThreadBSS;
return K;
}
void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
SmallVectorImpl<char> &Str) const {
Str.push_back(',');
Str.push_back('"');
if (!Kind.isMetadata())
Str.push_back('a');
if (Kind.isText())
Str.push_back('x');
if (Kind.isWriteable())
Str.push_back('w');
if (Kind.isMergeableConst() || Kind.isMergeableCString())
Str.push_back('M');
if (Kind.isMergeableCString())
Str.push_back('S');
if (Kind.isThreadLocal())
Str.push_back('T');
Str.push_back('"');
Str.push_back(',');
// If comment string is '@', e.g. as on ARM - use '%' instead
if (strcmp(CommentString, "@") == 0)
Str.push_back('%');
else
Str.push_back('@');
const char *KindStr;
if (Kind.isBSS())
KindStr = "nobits";
else
KindStr = "progbits";
Str.append(KindStr, KindStr+strlen(KindStr));
if (Kind.isMergeableCString()) {
// TODO: Eventually handle multiple byte character strings. For now, all
// mergable C strings are single byte.
Str.push_back(',');
Str.push_back('1');
} else if (Kind.isMergeableConst4()) {
Str.push_back(',');
Str.push_back('4');
} else if (Kind.isMergeableConst8()) {
Str.push_back(',');
Str.push_back('8');
} else if (Kind.isMergeableConst16()) {
Str.push_back(',');
Str.push_back('1');
Str.push_back('6');
}
}
//===----------------------------------------------------------------------===//
// Move to AsmPrinter (mangler access).
//===----------------------------------------------------------------------===//
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/StringExtras.h"
static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
if (Kind.isText()) return ".gnu.linkonce.t.";
if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
if (Kind.isThreadData()) return ".gnu.linkonce.td.";
if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
if (Kind.isBSS()) return ".gnu.linkonce.b.";
if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
return ".gnu.linkonce.d.rel.ro.";
}
const Section*
ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind) const {
// If this global is linkonce/weak and the target handles this by emitting it
// into a 'uniqued' section name, create and return the section now.
if (Kind.isWeak()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
// FIXME: Use mangler interface (PR4584).
std::string Name = Prefix+GV->getNameStr();
return getOrCreateSection(Name.c_str(), false, Kind.getKind());
}
if (Kind.isText()) return TextSection;
if (Kind.isMergeableCString()) {
const TargetData *TD = TM.getTargetData();
@ -119,103 +232,3 @@ ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const {
return SelectSectionForGlobal(0, Kind);
}
/// getFlagsForNamedSection - If this target wants to be able to infer
/// section flags based on the name of the section specified for a global
/// variable, it can implement this.
SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name,
SectionKind::Kind K) const {
if (Name[0] != '.') return K;
// Some lame default implementation based on some magic section names.
if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
return SectionKind::BSS;
if (strcmp(Name, ".tdata") == 0 ||
strncmp(Name, ".tdata.", 7) == 0 ||
strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
return SectionKind::ThreadData;
if (strcmp(Name, ".tbss") == 0 ||
strncmp(Name, ".tbss.", 6) == 0 ||
strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
return SectionKind::ThreadBSS;
return K;
}
const char *
ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind Kind) const{
if (Kind.isText()) return ".gnu.linkonce.t.";
if (Kind.isReadOnly()) return ".gnu.linkonce.r.";
if (Kind.isThreadData()) return ".gnu.linkonce.td.";
if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
if (Kind.isBSS()) return ".gnu.linkonce.b.";
if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local.";
assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
return ".gnu.linkonce.d.rel.ro.";
}
void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind,
SmallVectorImpl<char> &Str) const {
Str.push_back(',');
Str.push_back('"');
if (!Kind.isMetadata())
Str.push_back('a');
if (Kind.isText())
Str.push_back('x');
if (Kind.isWriteable())
Str.push_back('w');
if (Kind.isMergeableConst() || Kind.isMergeableCString())
Str.push_back('M');
if (Kind.isMergeableCString())
Str.push_back('S');
if (Kind.isThreadLocal())
Str.push_back('T');
Str.push_back('"');
Str.push_back(',');
// If comment string is '@', e.g. as on ARM - use '%' instead
if (strcmp(CommentString, "@") == 0)
Str.push_back('%');
else
Str.push_back('@');
const char *KindStr;
if (Kind.isBSS())
KindStr = "nobits";
else
KindStr = "progbits";
Str.append(KindStr, KindStr+strlen(KindStr));
if (Kind.isMergeableCString()) {
// TODO: Eventually handle multiple byte character strings. For now, all
// mergable C strings are single byte.
Str.push_back(',');
Str.push_back('1');
} else if (Kind.isMergeableConst4()) {
Str.push_back(',');
Str.push_back('4');
} else if (Kind.isMergeableConst8()) {
Str.push_back(',');
Str.push_back('8');
} else if (Kind.isMergeableConst16()) {
Str.push_back(',');
Str.push_back('1');
Str.push_back('6');
}
}

View File

@ -319,15 +319,6 @@ const Section *TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
return getOrCreateSection(GV->getSection().c_str(), false, GVKind);
}
// If this global is linkonce/weak and the target handles this by emitting it
// into a 'uniqued' section name, create and return the section now.
if (Kind.isWeak()) {
if (const char *Prefix = getSectionPrefixForUniqueGlobal(Kind)) {
// FIXME: Use mangler interface (PR4584).
std::string Name = Prefix+GV->getNameStr();
return getOrCreateSection(Name.c_str(), false, GVKind);
}
}
// Use default section depending on the 'type' of global
return SelectSectionForGlobal(GV, Kind);