introduce a section kind for common linkage. Use this to slightly
authorChris Lattner <sabre@nondot.org>
Tue, 19 Jan 2010 02:48:26 +0000 (02:48 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 19 Jan 2010 02:48:26 +0000 (02:48 +0000)
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

include/llvm/MC/SectionKind.h
lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
lib/Target/TargetLoweringObjectFile.cpp
lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp

index 945cff790a4876875c4f0cb01c1f0deebaef1c50..f125d1578f2278cdee5278e55020353c464739db 100644 (file)
@@ -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); }
index 2ba940bb49206f19cad1a98e9cd8dd44bf3e2018..9016f5c1124675abad996e4721885cc9edfc9409 100644 (file)
@@ -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".
index 28dd193deb2b9e648025907d522e3eb799486283..5e1942812630a67808050f75c9174b517896e270 100644 (file)
@@ -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;
   }
 
index 53d2955b62d79213ac66fab4ca78b5537284f534..0171193f121a92f2343d266b25330348bfadc273 100644 (file)
@@ -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.
 
index 26a181aea0db80cad6227b54f9969433017864f0..cd0558025b8ea39004a679f19747d34097b42137 100644 (file)
@@ -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;
index 3bf4c4c9af724d75d8c566da475a139bf3cd69af..383bc3180b35632a92633738763edf39a566c81c 100644 (file)
@@ -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);