Properly handle linkonce stuff

llvm-svn: 53296
This commit is contained in:
Anton Korobeynikov 2008-07-09 13:19:38 +00:00
parent 782a69505d
commit ca271dd426
4 changed files with 110 additions and 35 deletions

View File

@ -56,11 +56,6 @@ namespace llvm {
};
}
struct SectionInfo {
SectionKind::Kind kind;
SectionFlags::Flags flags;
};
class TargetMachine;
class CallInst;
class GlobalValue;
@ -476,6 +471,9 @@ namespace llvm {
/// global with all necessary flags and marks.
virtual std::string SectionForGlobal(const GlobalValue *GV) const;
virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
SectionKind::Kind kind) const;
// Accessors.
//
const char *getTextSection() const {

View File

@ -266,3 +266,26 @@ TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
return getDataSection();
}
std::string
TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
SectionKind::Kind kind) const {
switch (kind) {
case SectionKind::Text:
return ".llvm.linkonce.t." + GV->getName();
case SectionKind::Data:
return ".llvm.linkonce.d." + GV->getName();
case SectionKind::BSS:
return ".llvm.linkonce.b." + GV->getName();
case SectionKind::ROData:
case SectionKind::RODataMergeConst:
case SectionKind::RODataMergeStr:
return ".llvm.linkonce.r." + GV->getName();
case SectionKind::ThreadData:
return ".llvm.linkonce.td." + GV->getName();
case SectionKind::ThreadBSS:
return ".llvm.linkonce.tb." + GV->getName();
default:
assert(0 && "Unknown section kind");
}
}

View File

@ -375,6 +375,41 @@ unsigned X86TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
}
}
std::string X86TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
SectionKind::Kind kind) const {
const X86Subtarget *Subtarget = &X86TM->getSubtarget<X86Subtarget>();
switch (Subtarget->TargetType) {
case X86Subtarget::isDarwin:
if (kind == SectionKind::Text)
return "__TEXT,__textcoal_nt,coalesced,pure_instructions";
else
return "__DATA,__datacoal_nt,coalesced";
case X86Subtarget::isCygwin:
case X86Subtarget::isMingw:
switch (kind) {
case SectionKind::Text:
return ".text$linkonce" + GV->getName();
case SectionKind::Data:
case SectionKind::BSS:
case SectionKind::ThreadData:
case SectionKind::ThreadBSS:
return ".data$linkonce" + GV->getName();
case SectionKind::ROData:
case SectionKind::RODataMergeConst:
case SectionKind::RODataMergeStr:
return ".rdata$linkonce" + GV->getName();
default:
assert(0 && "Unknown section kind");
}
case X86Subtarget::isELF:
return TargetAsmInfo::UniqueSectionForGlobal(GV, kind);
default:
return "";
}
}
std::string X86TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
const X86Subtarget *Subtarget = &X86TM->getSubtarget<X86Subtarget>();
SectionKind::Kind kind = SectionKindForGlobal(GV);
@ -383,41 +418,58 @@ std::string X86TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
// FIXME: Should we use some hashing based on section name and just check
// flags?
// FIXME: It seems, that Darwin uses much more sections.
// Select section name
if (const Function *F = dyn_cast<Function>(GV)) {
// Implement here
} else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
if (GVar->hasSection()) {
// Honour section already set, if any
Name = GVar->getSection();
} else {
// Use default section depending on the 'type' of global
// FIXME: Handle linkonce stuff
switch (kind) {
case SectionKind::Data:
Name = DataSection;
if (GV->hasSection()) {
// Honour section already set, if any
Name = GV->getSection();
} else {
// Use default section depending on the 'type' of global
if (const Function *F = dyn_cast<Function>(GV)) {
switch (F->getLinkage()) {
default: assert(0 && "Unknown linkage type!");
case Function::InternalLinkage:
case Function::DLLExportLinkage:
case Function::ExternalLinkage:
Name = TextSection;
break;
case SectionKind::BSS:
Name = (BSSSection ? BSSSection : DataSection);
case Function::WeakLinkage:
case Function::LinkOnceLinkage:
Name = UniqueSectionForGlobal(F, kind);
break;
case SectionKind::ROData:
case SectionKind::RODataMergeStr:
case SectionKind::RODataMergeConst:
// FIXME: Temporary
Name = DataSection;
break;
case SectionKind::ThreadData:
Name = (TLSDataSection ? TLSDataSection : DataSection);
break;
case SectionKind::ThreadBSS:
Name = (TLSBSSSection ? TLSBSSSection : DataSection);
default:
assert(0 && "Unsuported section kind for global");
}
}
} else
assert(0 && "Unsupported global");
} else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
if (GVar->hasCommonLinkage() ||
GVar->hasLinkOnceLinkage() ||
GVar->hasWeakLinkage())
Name = UniqueSectionForGlobal(GVar, kind);
else {
switch (kind) {
case SectionKind::Data:
Name = DataSection;
break;
case SectionKind::BSS:
Name = (BSSSection ? BSSSection : DataSection);
break;
case SectionKind::ROData:
case SectionKind::RODataMergeStr:
case SectionKind::RODataMergeConst:
// FIXME: Temporary
Name = DataSection;
break;
case SectionKind::ThreadData:
Name = (TLSDataSection ? TLSDataSection : DataSection);
break;
case SectionKind::ThreadBSS:
Name = (TLSBSSSection ? TLSBSSSection : DataSection);
default:
assert(0 && "Unsuported section kind for global");
}
}
} else
assert(0 && "Unsupported global");
}
// Add all special flags, etc
switch (Subtarget->TargetType) {

View File

@ -28,6 +28,8 @@ namespace llvm {
virtual unsigned PreferredEHDataFormat(DwarfEncoding::Target Reason,
bool Global) const;
virtual std::string SectionForGlobal(const GlobalValue *GV) const;
virtual std::string UniqueSectionForGlobal(const GlobalValue* GV,
SectionKind::Kind kind) const;
private:
const X86TargetMachine* X86TM;