GV with null value initializer shouldn't go to BSS if it's meant for a mergeable...
[oota-llvm.git] / lib / Target / PowerPC / AsmPrinter / PPCAsmPrinter.cpp
index 8b37167f4ad3874a1adac59b7f6f274d939375b9..6c5d8b9d476756f94709c488fdf348d5baef839a 100644 (file)
@@ -292,13 +292,12 @@ namespace {
 
   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
   struct VISIBILITY_HIDDEN PPCLinuxAsmPrinter : public PPCAsmPrinter {
-
-    DwarfWriter DW;
+    DwarfWriter *DW;
     MachineModuleInfo *MMI;
 
     PPCLinuxAsmPrinter(raw_ostream &O, PPCTargetMachine &TM,
                     const TargetAsmInfo *T)
-      : PPCAsmPrinter(O, TM, T), DW(O, this, T), MMI(0) {
+      : PPCAsmPrinter(O, TM, T), DW(0), MMI(0) {
     }
 
     virtual const char *getPassName() const {
@@ -312,6 +311,7 @@ namespace {
     void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesAll();
       AU.addRequired<MachineModuleInfo>();
+      AU.addRequired<DwarfWriter>();
       PPCAsmPrinter::getAnalysisUsage(AU);
     }
 
@@ -322,12 +322,12 @@ namespace {
   /// OS X
   struct VISIBILITY_HIDDEN PPCDarwinAsmPrinter : public PPCAsmPrinter {
 
-    DwarfWriter DW;
+    DwarfWriter *DW;
     MachineModuleInfo *MMI;
-
+    raw_ostream &OS;
     PPCDarwinAsmPrinter(raw_ostream &O, PPCTargetMachine &TM,
                         const TargetAsmInfo *T)
-      : PPCAsmPrinter(O, TM, T), DW(O, this, T), MMI(0) {
+      : PPCAsmPrinter(O, TM, T), DW(0), MMI(0), OS(O) {
     }
 
     virtual const char *getPassName() const {
@@ -341,6 +341,7 @@ namespace {
     void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesAll();
       AU.addRequired<MachineModuleInfo>();
+      AU.addRequired<DwarfWriter>();
       PPCAsmPrinter::getAnalysisUsage(AU);
     }
 
@@ -583,6 +584,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   switch (F->getLinkage()) {
   default: assert(0 && "Unknown linkage type!");
+  case Function::PrivateLinkage:
   case Function::InternalLinkage:  // Symbols default to internal.
     break;
   case Function::ExternalLinkage:
@@ -602,7 +604,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   O << CurrentFnName << ":\n";
 
   // Emit pre-function debug information.
-  DW.BeginFunction(&MF);
+  DW->BeginFunction(&MF);
 
   // Print out code for the function.
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
@@ -627,7 +629,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   SwitchToSection(TAI->SectionForGlobal(F));
 
   // Emit post-function debug information.
-  DW.EndFunction(&MF);
+  DW->EndFunction(&MF);
 
   O.flush();
 
@@ -639,12 +641,11 @@ bool PPCLinuxAsmPrinter::doInitialization(Module &M) {
   bool Result = AsmPrinter::doInitialization(M);
 
   // Emit initial debug information.
-  DW.BeginModule(&M);
-
-  // AsmPrinter::doInitialization should have done this analysis.
-  MMI = getAnalysisToUpdate<MachineModuleInfo>();
+  MMI = getAnalysisIfAvailable<MachineModuleInfo>();
   assert(MMI);
-  DW.SetModuleInfo(MMI);
+  DW = getAnalysisIfAvailable<DwarfWriter>();
+  assert(DW && "DwarfWriter is not available");
+  DW->BeginModule(&M, MMI, O, this, TAI);
 
   // GNU as handles section names wrapped in quotes
   Mang->setUseQuotes(true);
@@ -679,14 +680,14 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
 
   Constant *C = GVar->getInitializer();
   const Type *Type = C->getType();
-  unsigned Size = TD->getABITypeSize(Type);
+  unsigned Size = TD->getTypePaddedSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
   SwitchToSection(TAI->SectionForGlobal(GVar));
 
   if (C->isNullValue() && /* FIXME: Verify correct */
       !GVar->hasSection() &&
-      (GVar->hasInternalLinkage() || GVar->hasExternalLinkage() ||
+      (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
        GVar->mayBeOverridden())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
@@ -695,7 +696,7 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
         O << "\t.type " << name << ", @object\n";
         O << name << ":\n";
         O << "\t.zero " << Size << '\n';
-      } else if (GVar->hasInternalLinkage()) {
+      } else if (GVar->hasLocalLinkage()) {
         O << TAI->getLCOMMDirective() << name << ',' << Size;
       } else {
         O << ".comm " << name << ',' << Size;
@@ -723,6 +724,7 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
       << "\t.type " << name << ", @object\n";
     // FALL THROUGH
    case GlobalValue::InternalLinkage:
+   case GlobalValue::PrivateLinkage:
     break;
    default:
     cerr << "Unknown linkage type!";
@@ -753,7 +755,7 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
   // TODO
 
   // Emit initial debug information.
-  DW.EndModule();
+  DW->EndModule();
 
   return AsmPrinter::doFinalization(M);
 }
@@ -774,6 +776,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   switch (F->getLinkage()) {
   default: assert(0 && "Unknown linkage type!");
+  case Function::PrivateLinkage:
   case Function::InternalLinkage:  // Symbols default to internal.
     break;
   case Function::ExternalLinkage:
@@ -792,7 +795,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   O << CurrentFnName << ":\n";
 
   // Emit pre-function debug information.
-  DW.BeginFunction(&MF);
+  DW->BeginFunction(&MF);
 
   // If the function is empty, then we need to emit *something*. Otherwise, the
   // function's label might be associated with something that it wasn't meant to
@@ -821,7 +824,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
 
   // Emit post-function debug information.
-  DW.EndFunction(&MF);
+  DW->EndFunction(&MF);
 
   // We didn't modify anything.
   return false;
@@ -854,13 +857,13 @@ bool PPCDarwinAsmPrinter::doInitialization(Module &M) {
   bool Result = AsmPrinter::doInitialization(M);
 
   // Emit initial debug information.
-  DW.BeginModule(&M);
-
   // We need this for Personality functions.
   // AsmPrinter::doInitialization should have done this analysis.
-  MMI = getAnalysisToUpdate<MachineModuleInfo>();
+  MMI = getAnalysisIfAvailable<MachineModuleInfo>();
   assert(MMI);
-  DW.SetModuleInfo(MMI);
+  DW = getAnalysisIfAvailable<DwarfWriter>();
+  assert(DW && "DwarfWriter is not available");
+  DW->BeginModule(&M, MMI, O, this, TAI);
 
   // Darwin wants symbols to be quoted if they have complex names.
   Mang->setUseQuotes(true);
@@ -904,22 +907,23 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
 
   Constant *C = GVar->getInitializer();
   const Type *Type = C->getType();
-  unsigned Size = TD->getABITypeSize(Type);
+  unsigned Size = TD->getTypePaddedSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
   SwitchToSection(TAI->SectionForGlobal(GVar));
 
   if (C->isNullValue() && /* FIXME: Verify correct */
       !GVar->hasSection() &&
-      (GVar->hasInternalLinkage() || GVar->hasExternalLinkage() ||
-       GVar->mayBeOverridden())) {
+      (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
+       GVar->mayBeOverridden()) &&
+      TAI->SectionKindForGlobal(GVar) != SectionKind::RODataMergeStr) {
     if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
     if (GVar->hasExternalLinkage()) {
       O << "\t.globl " << name << '\n';
       O << "\t.zerofill __DATA, __common, " << name << ", "
         << Size << ", " << Align;
-    } else if (GVar->hasInternalLinkage()) {
+    } else if (GVar->hasLocalLinkage()) {
       O << TAI->getLCOMMDirective() << name << ',' << Size << ',' << Align;
     } else if (!GVar->hasCommonLinkage()) {
       O << "\t.globl " << name << '\n'
@@ -957,6 +961,7 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
     O << "\t.globl " << name << '\n';
     // FALL THROUGH
    case GlobalValue::InternalLinkage:
+   case GlobalValue::PrivateLinkage:
     break;
    default:
     cerr << "Unknown linkage type!";
@@ -1122,7 +1127,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
 
 
   // Emit initial debug information.
-  DW.EndModule();
+  DW->EndModule();
 
   // Funny Darwin hack: This flag tells the linker that no global symbols
   // contain code that falls through to other global symbols (e.g. the obvious