introduce a section kind for common linkage. Use this to slightly

simplify and commonize some of the asmprinter logic for globals.

This also avoids printing the MCSection for .zerofill, which broke
the llvm-gcc build.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93843 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2010-01-19 02:48:26 +00:00
parent 129e1872c2
commit a3839bc371
6 changed files with 107 additions and 25 deletions

View File

@ -88,6 +88,11 @@ class SectionKind {
/// BSS - Zero initialized writeable data. /// BSS - Zero initialized writeable data.
BSS, BSS,
/// Common - Data with common linkage. These represent tentative
/// definitions, which always have a zero initializer and are never
/// marked 'constant'.
Common,
/// DataRel - This is the most general form of data that is written /// DataRel - This is the most general form of data that is written
/// to by the program, it can have random relocations to arbitrary /// to by the program, it can have random relocations to arbitrary
/// globals. /// globals.
@ -158,10 +163,11 @@ public:
bool isThreadData() const { return K == ThreadData; } bool isThreadData() const { return K == ThreadData; }
bool isGlobalWriteableData() const { bool isGlobalWriteableData() const {
return isBSS() || isDataRel() || isReadOnlyWithRel(); return isBSS() || isCommon() || isDataRel() || isReadOnlyWithRel();
} }
bool isBSS() const { return K == BSS; } bool isBSS() const { return K == BSS; }
bool isCommon() const { return K == Common; }
bool isDataRel() const { bool isDataRel() const {
return K == DataRel || K == DataRelLocal || K == DataNoRel; return K == DataRel || K == DataRelLocal || K == DataNoRel;
@ -207,6 +213,7 @@ public:
static SectionKind getThreadBSS() { return get(ThreadBSS); } static SectionKind getThreadBSS() { return get(ThreadBSS); }
static SectionKind getThreadData() { return get(ThreadData); } static SectionKind getThreadData() { return get(ThreadData); }
static SectionKind getBSS() { return get(BSS); } static SectionKind getBSS() { return get(BSS); }
static SectionKind getCommon() { return get(Common); }
static SectionKind getDataRel() { return get(DataRel); } static SectionKind getDataRel() { return get(DataRel); }
static SectionKind getDataRelLocal() { return get(DataRelLocal); } static SectionKind getDataRelLocal() { return get(DataRelLocal); }
static SectionKind getDataNoRel() { return get(DataNoRel); } static SectionKind getDataNoRel() { return get(DataNoRel); }

View File

@ -1197,9 +1197,26 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
O << "\t.type " << *GVarSym << ",%object\n"; O << "\t.type " << *GVarSym << ",%object\n";
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM); SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
// Handle normal common symbols.
if (GVKind.isCommon()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
O << ".comm " << *GVarSym << ',' << Size;
if (MAI->getCOMMDirectiveTakesAlignment())
O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
if (VerboseAsm) {
O << "\t\t" << MAI->getCommentString() << " '";
WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
O << '\'';
}
O << '\n';
return;
}
const MCSection *TheSection = const MCSection *TheSection =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM); getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
OutStreamer.SwitchSection(TheSection);
// Handle the zerofill directive on darwin, which is a special form of BSS // Handle the zerofill directive on darwin, which is a special form of BSS
// emission. // emission.
@ -1215,6 +1232,8 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
} }
} }
OutStreamer.SwitchSection(TheSection);
// FIXME: get this stuff from section kind flags. // FIXME: get this stuff from section kind flags.
if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() && if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
// Don't put things that should go in the cstring section into "comm". // Don't put things that should go in the cstring section into "comm".

View File

@ -714,8 +714,27 @@ void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
unsigned Size = TD->getTypeAllocSize(Type); unsigned Size = TD->getTypeAllocSize(Type);
unsigned Align = TD->getPreferredAlignmentLog(GVar); unsigned Align = TD->getPreferredAlignmentLog(GVar);
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang, SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
TM));
// Handle normal common symbols.
if (GVKind.isCommon()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
O << ".comm " << *GVarSym << ',' << Size;
if (MAI->getCOMMDirectiveTakesAlignment())
O << ',' << Align;
if (VerboseAsm) {
O << "\t\t" << MAI->getCommentString() << " '";
WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
O << '\'';
}
O << '\n';
return;
}
OutStreamer.SwitchSection(getObjFileLowering().
SectionForGlobal(GVar, GVKind, Mang, TM));
if (C->isNullValue() && /* FIXME: Verify correct */ if (C->isNullValue() && /* FIXME: Verify correct */
!GVar->hasSection() && !GVar->hasSection() &&
@ -945,9 +964,26 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
unsigned Align = TD->getPreferredAlignmentLog(GVar); unsigned Align = TD->getPreferredAlignmentLog(GVar);
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM); SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
// Handle normal common symbols.
if (GVKind.isCommon()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
O << ".comm " << *GVarSym << ',' << Size;
if (MAI->getCOMMDirectiveTakesAlignment())
O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
if (VerboseAsm) {
O << "\t\t" << MAI->getCommentString() << " '";
WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
O << '\'';
}
O << '\n';
return;
}
const MCSection *TheSection = const MCSection *TheSection =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM); getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
OutStreamer.SwitchSection(TheSection);
// Handle the zerofill directive on darwin, which is a special form of BSS // Handle the zerofill directive on darwin, which is a special form of BSS
// emission. // emission.
@ -963,6 +999,8 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
} }
} }
OutStreamer.SwitchSection(TheSection);
/// FIXME: Drive this off the section! /// FIXME: Drive this off the section!
if (C->isNullValue() && /* FIXME: Verify correct */ if (C->isNullValue() && /* FIXME: Verify correct */
!GVar->hasSection() && !GVar->hasSection() &&
@ -974,7 +1012,14 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
if (GVar->hasLocalLinkage()) { if (GVar->hasLocalLinkage()) {
O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size << ',' << Align; O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size << ',' << Align;
} else if (!GVar->hasCommonLinkage()) {
if (VerboseAsm) {
O << "\t\t" << MAI->getCommentString() << " '";
WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
O << "'";
}
O << '\n';
} else {
O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective(); O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
O << *GVarSym << '\n'; O << *GVarSym << '\n';
EmitAlignment(Align, GVar); EmitAlignment(Align, GVar);
@ -985,19 +1030,7 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
} }
O << '\n'; O << '\n';
EmitGlobalConstant(C); EmitGlobalConstant(C);
return;
} else {
O << ".comm " << *GVarSym << ',' << Size;
// Darwin 9 and above support aligned common data.
if (Subtarget.isDarwin9())
O << ',' << Align;
} }
if (VerboseAsm) {
O << "\t\t" << MAI->getCommentString() << " '";
WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
O << "'";
}
O << '\n';
return; return;
} }

View File

@ -318,7 +318,7 @@ void SystemZAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
if (C->isNullValue() && !GVar->hasSection() && if (C->isNullValue() && !GVar->hasSection() &&
!GVar->isThreadLocal() && !GVar->isThreadLocal() &&
(GVar->hasLocalLinkage() || GVar->isWeakForLinker())) { (GVar->hasLocalLinkage() || GVar->hasCommonLinkage())) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.

View File

@ -141,6 +141,10 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
return SectionKind::getThreadData(); return SectionKind::getThreadData();
} }
// Variables with common linkage always get classified as common.
if (GVar->hasCommonLinkage())
return SectionKind::getCommon();
// Variable can be easily put to BSS section. // Variable can be easily put to BSS section.
if (isSuitableForBSS(GVar)) if (isSuitableForBSS(GVar))
return SectionKind::getBSS(); return SectionKind::getBSS();
@ -577,7 +581,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
// If this global is linkonce/weak and the target handles this by emitting it // 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. // into a 'uniqued' section name, create and return the section now.
if (GV->isWeakForLinker()) { if (GV->isWeakForLinker() && !Kind.isCommon()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind); const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
SmallString<128> Name; SmallString<128> Name;
Name.append(Prefix, Prefix+strlen(Prefix)); Name.append(Prefix, Prefix+strlen(Prefix));
@ -630,7 +634,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
if (Kind.isThreadData()) return TLSDataSection; if (Kind.isThreadData()) return TLSDataSection;
if (Kind.isThreadBSS()) return TLSBSSSection; if (Kind.isThreadBSS()) return TLSBSSSection;
if (Kind.isBSS()) return BSSSection; if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
if (Kind.isDataNoRel()) return DataSection; if (Kind.isDataNoRel()) return DataSection;
if (Kind.isDataRelLocal()) return DataRelLocalSection; if (Kind.isDataRelLocal()) return DataRelLocalSection;

View File

@ -676,9 +676,26 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
O << "\t.type\t" << *GVarSym << ",@object\n"; O << "\t.type\t" << *GVarSym << ",@object\n";
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM); SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
// Handle normal common symbols.
if (GVKind.isCommon()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
O << ".comm " << *GVarSym << ',' << Size;
if (MAI->getCOMMDirectiveTakesAlignment())
O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
if (VerboseAsm) {
O << "\t\t" << MAI->getCommentString() << " '";
WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
O << '\'';
}
O << '\n';
return;
}
const MCSection *TheSection = const MCSection *TheSection =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM); getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
OutStreamer.SwitchSection(TheSection);
// Handle the zerofill directive on darwin, which is a special form of BSS // Handle the zerofill directive on darwin, which is a special form of BSS
// emission. // emission.
@ -694,6 +711,8 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
} }
} }
OutStreamer.SwitchSection(TheSection);
// FIXME: get this stuff from section kind flags. // FIXME: get this stuff from section kind flags.
if (C->isNullValue() && !GVar->hasSection() && if (C->isNullValue() && !GVar->hasSection() &&
// Don't put things that should go in the cstring section into "comm". // Don't put things that should go in the cstring section into "comm".
@ -707,7 +726,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
O << LComm << *GVarSym << ',' << Size; O << LComm << *GVarSym << ',' << Size;
if (Subtarget->isTargetDarwin()) if (Subtarget->isTargetDarwin())
O << ',' << Align; O << ',' << Align;
} else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) { } else if (Subtarget->isTargetDarwin()) {
OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global); OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
O << MAI->getWeakDefDirective() << *GVarSym << '\n'; O << MAI->getWeakDefDirective() << *GVarSym << '\n';
EmitAlignment(Align, GVar); EmitAlignment(Align, GVar);