aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-01-19 02:48:26 +0000
committerChris Lattner <sabre@nondot.org>2010-01-19 02:48:26 +0000
commita3839bc3714e6a84222f45cf4c0f1a20a88b10cd (patch)
tree63f5a4d489473d1124be4d1d1a4ba54dd8514e1c
parent129e1872c276dc76f08862276bf7433b19643cab (diff)
downloadexternal_llvm-a3839bc3714e6a84222f45cf4c0f1a20a88b10cd.zip
external_llvm-a3839bc3714e6a84222f45cf4c0f1a20a88b10cd.tar.gz
external_llvm-a3839bc3714e6a84222f45cf4c0f1a20a88b10cd.tar.bz2
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
-rw-r--r--include/llvm/MC/SectionKind.h9
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp23
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp67
-rw-r--r--lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp2
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp8
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp23
6 files changed, 107 insertions, 25 deletions
diff --git a/include/llvm/MC/SectionKind.h b/include/llvm/MC/SectionKind.h
index 945cff7..f125d15 100644
--- a/include/llvm/MC/SectionKind.h
+++ b/include/llvm/MC/SectionKind.h
@@ -87,6 +87,11 @@ class SectionKind {
/// BSS - Zero initialized writeable data.
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
/// to by the program, it can have random relocations to arbitrary
@@ -158,10 +163,11 @@ public:
bool isThreadData() const { return K == ThreadData; }
bool isGlobalWriteableData() const {
- return isBSS() || isDataRel() || isReadOnlyWithRel();
+ return isBSS() || isCommon() || isDataRel() || isReadOnlyWithRel();
}
bool isBSS() const { return K == BSS; }
+ bool isCommon() const { return K == Common; }
bool isDataRel() const {
return K == DataRel || K == DataRelLocal || K == DataNoRel;
@@ -207,6 +213,7 @@ public:
static SectionKind getThreadBSS() { return get(ThreadBSS); }
static SectionKind getThreadData() { return get(ThreadData); }
static SectionKind getBSS() { return get(BSS); }
+ static SectionKind getCommon() { return get(Common); }
static SectionKind getDataRel() { return get(DataRel); }
static SectionKind getDataRelLocal() { return get(DataRelLocal); }
static SectionKind getDataNoRel() { return get(DataNoRel); }
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 2ba940b..9016f5c 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -1197,10 +1197,27 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
O << "\t.type " << *GVarSym << ",%object\n";
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 =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
+
// Handle the zerofill directive on darwin, which is a special form of BSS
// emission.
if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
@@ -1215,6 +1232,8 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
}
}
+ OutStreamer.SwitchSection(TheSection);
+
// FIXME: get this stuff from section kind flags.
if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
// Don't put things that should go in the cstring section into "comm".
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index 28dd193..5e19428 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -714,8 +714,27 @@ void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
unsigned Size = TD->getTypeAllocSize(Type);
unsigned Align = TD->getPreferredAlignmentLog(GVar);
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- 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 << ',' << 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 */
!GVar->hasSection() &&
@@ -945,10 +964,27 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
unsigned Align = TD->getPreferredAlignmentLog(GVar);
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 =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
+
// Handle the zerofill directive on darwin, which is a special form of BSS
// emission.
if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
@@ -963,6 +999,8 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
}
}
+ OutStreamer.SwitchSection(TheSection);
+
/// FIXME: Drive this off the section!
if (C->isNullValue() && /* FIXME: Verify correct */
!GVar->hasSection() &&
@@ -974,7 +1012,14 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
if (GVar->hasLocalLinkage()) {
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 << *GVarSym << '\n';
EmitAlignment(Align, GVar);
@@ -985,19 +1030,7 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
}
O << '\n';
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;
}
diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
index 53d2955..0171193 100644
--- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
@@ -318,7 +318,7 @@ void SystemZAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
if (C->isNullValue() && !GVar->hasSection() &&
!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
+ (GVar->hasLocalLinkage() || GVar->hasCommonLinkage())) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index 26a181a..cd05580 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -141,6 +141,10 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
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.
if (isSuitableForBSS(GVar))
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
// into a 'uniqued' section name, create and return the section now.
- if (GV->isWeakForLinker()) {
+ if (GV->isWeakForLinker() && !Kind.isCommon()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
SmallString<128> Name;
Name.append(Prefix, Prefix+strlen(Prefix));
@@ -630,7 +634,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
if (Kind.isThreadData()) return TLSDataSection;
if (Kind.isThreadBSS()) return TLSBSSSection;
- if (Kind.isBSS()) return BSSSection;
+ if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
if (Kind.isDataNoRel()) return DataSection;
if (Kind.isDataRelLocal()) return DataRelLocalSection;
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index 3bf4c4c9..383bc31 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -676,9 +676,26 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
O << "\t.type\t" << *GVarSym << ",@object\n";
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 =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
// Handle the zerofill directive on darwin, which is a special form of BSS
// emission.
@@ -693,6 +710,8 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
return;
}
}
+
+ OutStreamer.SwitchSection(TheSection);
// FIXME: get this stuff from section kind flags.
if (C->isNullValue() && !GVar->hasSection() &&
@@ -707,7 +726,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
O << LComm << *GVarSym << ',' << Size;
if (Subtarget->isTargetDarwin())
O << ',' << Align;
- } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
+ } else if (Subtarget->isTargetDarwin()) {
OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
O << MAI->getWeakDefDirective() << *GVarSym << '\n';
EmitAlignment(Align, GVar);