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 c5ed305a8d58bd36869814a951ba3071177b47e8..6c5d8b9d476756f94709c488fdf348d5baef839a 100644 (file)
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
-#include <set>
+#include "llvm/ADT/StringSet.h"
 using namespace llvm;
 
 STATISTIC(EmittedInsts, "Number of machine instrs printed");
 
 namespace {
   struct VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter {
-    std::set<std::string> FnStubs, GVStubs;
+    StringSet<> FnStubs, GVStubs, HiddenGVStubs;
     const PPCSubtarget &Subtarget;
 
-    PPCAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
+    PPCAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
       : AsmPrinter(O, TM, T), Subtarget(TM.getSubtarget<PPCSubtarget>()) {
     }
 
@@ -122,9 +123,9 @@ namespace {
 
     void printOperand(const MachineInstr *MI, unsigned OpNo) {
       const MachineOperand &MO = MI->getOperand(OpNo);
-      if (MO.isRegister()) {
+      if (MO.isReg()) {
         printRegister(MO, false);
-      } else if (MO.isImmediate()) {
+      } else if (MO.isImm()) {
         O << MO.getImm();
       } else {
         printOp(MO);
@@ -159,7 +160,7 @@ namespace {
       O << (unsigned short)MI->getOperand(OpNo).getImm();
     }
     void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      if (MI->getOperand(OpNo).isImmediate()) {
+      if (MI->getOperand(OpNo).isImm()) {
         O << (short)(MI->getOperand(OpNo).getImm()*4);
       } else {
         O << "lo16(";
@@ -173,7 +174,7 @@ namespace {
     void printBranchOperand(const MachineInstr *MI, unsigned OpNo) {
       // Branches can take an immediate operand.  This is used by the branch
       // selection pass to print $+8, an eight byte displacement from the PC.
-      if (MI->getOperand(OpNo).isImmediate()) {
+      if (MI->getOperand(OpNo).isImm()) {
         O << "$+" << MI->getOperand(OpNo).getImm()*4;
       } else {
         printOp(MI->getOperand(OpNo));
@@ -213,7 +214,7 @@ namespace {
       O << "\"L" << getFunctionNumber() << "$pb\":";
     }
     void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
-      if (MI->getOperand(OpNo).isImmediate()) {
+      if (MI->getOperand(OpNo).isImm()) {
         printS16ImmOperand(MI, OpNo);
       } else {
         if (Subtarget.isDarwin()) O << "ha16(";
@@ -227,7 +228,7 @@ namespace {
       }
     }
     void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
-      if (MI->getOperand(OpNo).isImmediate()) {
+      if (MI->getOperand(OpNo).isImm()) {
         printS16ImmOperand(MI, OpNo);
       } else {
         if (Subtarget.isDarwin()) O << "lo16(";
@@ -249,7 +250,7 @@ namespace {
     void printMemRegImm(const MachineInstr *MI, unsigned OpNo) {
       printSymbolLo(MI, OpNo);
       O << '(';
-      if (MI->getOperand(OpNo+1).isRegister() &&
+      if (MI->getOperand(OpNo+1).isReg() &&
           MI->getOperand(OpNo+1).getReg() == PPC::R0)
         O << "0";
       else
@@ -257,12 +258,12 @@ namespace {
       O << ')';
     }
     void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo) {
-      if (MI->getOperand(OpNo).isImmediate())
+      if (MI->getOperand(OpNo).isImm())
         printS16X4ImmOperand(MI, OpNo);
       else
         printSymbolLo(MI, OpNo);
       O << '(';
-      if (MI->getOperand(OpNo+1).isRegister() &&
+      if (MI->getOperand(OpNo+1).isReg() &&
           MI->getOperand(OpNo+1).getReg() == PPC::R0)
         O << "0";
       else
@@ -291,13 +292,12 @@ namespace {
 
   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
   struct VISIBILITY_HIDDEN PPCLinuxAsmPrinter : public PPCAsmPrinter {
-
-    DwarfWriter DW;
+    DwarfWriter *DW;
     MachineModuleInfo *MMI;
 
-    PPCLinuxAsmPrinter(std::ostream &O, PPCTargetMachine &TM,
+    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 {
@@ -311,12 +311,10 @@ namespace {
     void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesAll();
       AU.addRequired<MachineModuleInfo>();
+      AU.addRequired<DwarfWriter>();
       PPCAsmPrinter::getAnalysisUsage(AU);
     }
 
-    /// getSectionForFunction - Return the section that we should emit the
-    /// specified function body into.
-    virtual std::string getSectionForFunction(const Function &F) const;
     void printModuleLevelGV(const GlobalVariable* GVar);
   };
 
@@ -324,12 +322,12 @@ namespace {
   /// OS X
   struct VISIBILITY_HIDDEN PPCDarwinAsmPrinter : public PPCAsmPrinter {
 
-    DwarfWriter DW;
+    DwarfWriter *DW;
     MachineModuleInfo *MMI;
-
-    PPCDarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM,
+    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 {
@@ -343,12 +341,10 @@ namespace {
     void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesAll();
       AU.addRequired<MachineModuleInfo>();
+      AU.addRequired<DwarfWriter>();
       PPCAsmPrinter::getAnalysisUsage(AU);
     }
 
-    /// getSectionForFunction - Return the section that we should emit the
-    /// specified function body into.
-    virtual std::string getSectionForFunction(const Function &F) const;
     void printModuleLevelGV(const GlobalVariable* GVar);
   };
 } // end of anonymous namespace
@@ -392,10 +388,18 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
 
     // External or weakly linked global variables need non-lazily-resolved stubs
     if (TM.getRelocationModel() != Reloc::Static) {
-      if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
-            GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
-        GVStubs.insert(Name);
-        printSuffixedName(Name, "$non_lazy_ptr");
+      if (GV->isDeclaration() || GV->mayBeOverridden()) {
+        if (GV->hasHiddenVisibility()) {
+          if (!GV->isDeclaration() && !GV->hasCommonLinkage())
+            O << Name;
+          else {
+            HiddenGVStubs.insert(Name);
+            printSuffixedName(Name, "$non_lazy_ptr");
+          }
+        } else {
+          GVStubs.insert(Name);
+          printSuffixedName(Name, "$non_lazy_ptr");
+        }
         if (GV->hasExternalWeakLinkage())
           ExtWeakSymbols.insert(GV);
         return;
@@ -403,10 +407,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
     }
     O << Name;
 
-    if (MO.getOffset() > 0)
-      O << "+" << MO.getOffset();
-    else if (MO.getOffset() < 0)
-      O << MO.getOffset();
+    printOffset(MO.getOffset());
 
     if (GV->hasExternalWeakLinkage())
       ExtWeakSymbols.insert(GV);
@@ -424,7 +425,10 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
 void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) {
   std::string Name = getGlobalLinkName(GV);
   if (TM.getRelocationModel() != Reloc::Static) {
-    GVStubs.insert(Name);
+    if (GV->hasHiddenVisibility())
+      HiddenGVStubs.insert(Name);
+    else
+      GVStubs.insert(Name);
     printSuffixedName(Name, "$non_lazy_ptr");
     return;
   }
@@ -448,16 +452,16 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
       return false;
     case 'L': // Write second word of DImode reference.
       // Verify that this operand has two consecutive registers.
-      if (!MI->getOperand(OpNo).isRegister() ||
+      if (!MI->getOperand(OpNo).isReg() ||
           OpNo+1 == MI->getNumOperands() ||
-          !MI->getOperand(OpNo+1).isRegister())
+          !MI->getOperand(OpNo+1).isReg())
         return true;
       ++OpNo;   // Return the high-part.
       break;
     case 'I':
       // Write 'i' if an integer constant, otherwise nothing.  Used to print
       // addi vs add, etc.
-      if (MI->getOperand(OpNo).isImmediate())
+      if (MI->getOperand(OpNo).isImm())
         O << "i";
       return false;
     }
@@ -472,7 +476,7 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
                                           const char *ExtraCode) {
   if (ExtraCode && ExtraCode[0])
     return true; // Unknown modifier.
-  if (MI->getOperand(OpNo).isRegister())
+  if (MI->getOperand(OpNo).isReg())
     printMemRegReg(MI, OpNo);
   else
     printMemRegImm(MI, OpNo);
@@ -576,10 +580,11 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Print out labels for the function.
   const Function *F = MF.getFunction();
-  SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
+  SwitchToSection(TAI->SectionForGlobal(F));
 
   switch (F->getLinkage()) {
   default: assert(0 && "Unknown linkage type!");
+  case Function::PrivateLinkage:
   case Function::InternalLinkage:  // Symbols default to internal.
     break;
   case Function::ExternalLinkage:
@@ -599,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();
@@ -621,8 +626,12 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   // Print out jump tables referenced by the function.
   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
 
+  SwitchToSection(TAI->SectionForGlobal(F));
+
   // Emit post-function debug information.
-  DW.EndFunction();
+  DW->EndFunction(&MF);
+
+  O.flush();
 
   // We didn't modify anything.
   return false;
@@ -632,24 +641,23 @@ 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);
 
-  SwitchToTextSection(TAI->getTextSection());
+  SwitchToSection(TAI->getTextSection());
 
   return Result;
 }
 
 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
 /// Don't print things like \n or \0.
-static void PrintUnmangledNameSafely(const Value *V, std::ostream &OS) {
+static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
        Name != E; ++Name)
     if (isprint(*Name))
@@ -667,21 +675,20 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
     return;
 
   std::string name = Mang->getValueName(GVar);
-  std::string SectionName = TAI->SectionForGlobal(GVar);
 
   printVisibility(name, GVar->getVisibility());
 
   Constant *C = GVar->getInitializer();
   const Type *Type = C->getType();
-  unsigned Size = TD->getABITypeSize(Type);
+  unsigned Size = TD->getTypePaddedSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
-  SwitchToDataSection(SectionName.c_str());
+  SwitchToSection(TAI->SectionForGlobal(GVar));
 
   if (C->isNullValue() && /* FIXME: Verify correct */
       !GVar->hasSection() &&
-      (GVar->hasInternalLinkage() || GVar->hasExternalLinkage() ||
-       GVar->isWeakForLinker())) {
+      (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
+       GVar->mayBeOverridden())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
       if (GVar->hasExternalLinkage()) {
@@ -689,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;
@@ -717,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!";
@@ -747,19 +755,11 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
   // TODO
 
   // Emit initial debug information.
-  DW.EndModule();
+  DW->EndModule();
 
   return AsmPrinter::doFinalization(M);
 }
 
-std::string PPCLinuxAsmPrinter::getSectionForFunction(const Function &F) const {
-  return TAI->SectionForGlobal(&F);
-}
-
-std::string PPCDarwinAsmPrinter::getSectionForFunction(const Function &F) const {
-  return TAI->SectionForGlobal(&F);
-}
-
 /// runOnMachineFunction - This uses the printMachineInstruction()
 /// method to print assembly for each instruction.
 ///
@@ -772,10 +772,11 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Print out labels for the function.
   const Function *F = MF.getFunction();
-  SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
+  SwitchToSection(TAI->SectionForGlobal(F));
 
   switch (F->getLinkage()) {
   default: assert(0 && "Unknown linkage type!");
+  case Function::PrivateLinkage:
   case Function::InternalLinkage:  // Symbols default to internal.
     break;
   case Function::ExternalLinkage:
@@ -790,11 +791,11 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   printVisibility(CurrentFnName, F->getVisibility());
 
-  EmitAlignment(OptimizeForSize ? 2 : 4, F);
+  EmitAlignment(F->hasFnAttr(Attribute::OptimizeForSize) ? 2 : 4, F);
   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
@@ -823,7 +824,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
 
   // Emit post-function debug information.
-  DW.EndFunction();
+  DW->EndFunction(&MF);
 
   // We didn't modify anything.
   return false;
@@ -856,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);
@@ -878,7 +879,7 @@ bool PPCDarwinAsmPrinter::doInitialization(Module &M) {
     SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
                         "pure_instructions,16");
   }
-  SwitchToTextSection(TAI->getTextSection());
+  SwitchToSection(TAI->getTextSection());
 
   return Result;
 }
@@ -901,28 +902,28 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
   }
 
   std::string name = Mang->getValueName(GVar);
-  std::string SectionName = TAI->SectionForGlobal(GVar);
 
   printVisibility(name, GVar->getVisibility());
 
   Constant *C = GVar->getInitializer();
   const Type *Type = C->getType();
-  unsigned Size = TD->getABITypeSize(Type);
+  unsigned Size = TD->getTypePaddedSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
 
-  SwitchToDataSection(SectionName.c_str());
+  SwitchToSection(TAI->SectionForGlobal(GVar));
 
   if (C->isNullValue() && /* FIXME: Verify correct */
       !GVar->hasSection() &&
-      (GVar->hasInternalLinkage() || GVar->hasExternalLinkage() ||
-       GVar->isWeakForLinker())) {
+      (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'
@@ -960,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!";
@@ -993,51 +995,70 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
 
   // Output stubs for dynamically-linked functions
   if (TM.getRelocationModel() == Reloc::PIC_) {
-    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
+    for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
          i != e; ++i) {
       SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
                           "pure_instructions,32");
       EmitAlignment(4);
-      std::string p = *i;
-      std::string L0p = (p[0]=='\"') ? "\"L0$" + p.substr(1) : "L0$" + p ;
+      const char *p = i->getKeyData();
+      bool hasQuote = p[0]=='\"';
       printSuffixedName(p, "$stub");
       O << ":\n";
-      O << "\t.indirect_symbol " << *i << '\n';
+      O << "\t.indirect_symbol " << p << '\n';
       O << "\tmflr r0\n";
-      O << "\tbcl 20,31," << L0p << '\n';
-      O << L0p << ":\n";
+      O << "\tbcl 20,31,";
+      if (hasQuote)
+        O << "\"L0$" << &p[1];
+      else
+        O << "L0$" << p;
+      O << '\n';
+      if (hasQuote)
+        O << "\"L0$" << &p[1];
+      else
+        O << "L0$" << p;
+      O << ":\n";
       O << "\tmflr r11\n";
       O << "\taddis r11,r11,ha16(";
       printSuffixedName(p, "$lazy_ptr");
-      O << "-" << L0p << ")\n";
+      O << "-";
+      if (hasQuote)
+        O << "\"L0$" << &p[1];
+      else
+        O << "L0$" << p;
+      O << ")\n";
       O << "\tmtlr r0\n";
       if (isPPC64)
         O << "\tldu r12,lo16(";
       else
         O << "\tlwzu r12,lo16(";
       printSuffixedName(p, "$lazy_ptr");
-      O << "-" << L0p << ")(r11)\n";
+      O << "-";
+      if (hasQuote)
+        O << "\"L0$" << &p[1];
+      else
+        O << "L0$" << p;
+      O << ")(r11)\n";
       O << "\tmtctr r12\n";
       O << "\tbctr\n";
       SwitchToDataSection(".lazy_symbol_pointer");
       printSuffixedName(p, "$lazy_ptr");
       O << ":\n";
-      O << "\t.indirect_symbol " << *i << '\n';
+      O << "\t.indirect_symbol " << p << '\n';
       if (isPPC64)
         O << "\t.quad dyld_stub_binding_helper\n";
       else
         O << "\t.long dyld_stub_binding_helper\n";
     }
   } else {
-    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
+    for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
          i != e; ++i) {
       SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
                           "pure_instructions,16");
       EmitAlignment(4);
-      std::string p = *i;
+      const char *p = i->getKeyData();
       printSuffixedName(p, "$stub");
       O << ":\n";
-      O << "\t.indirect_symbol " << *i << '\n';
+      O << "\t.indirect_symbol " << p << '\n';
       O << "\tlis r11,ha16(";
       printSuffixedName(p, "$lazy_ptr");
       O << ")\n";
@@ -1052,7 +1073,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
       SwitchToDataSection(".lazy_symbol_pointer");
       printSuffixedName(p, "$lazy_ptr");
       O << ":\n";
-      O << "\t.indirect_symbol " << *i << '\n';
+      O << "\t.indirect_symbol " << p << '\n';
       if (isPPC64)
         O << "\t.quad dyld_stub_binding_helper\n";
       else
@@ -1075,12 +1096,12 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
   // Output stubs for external and common global variables.
   if (!GVStubs.empty()) {
     SwitchToDataSection(".non_lazy_symbol_pointer");
-    for (std::set<std::string>::iterator I = GVStubs.begin(),
-         E = GVStubs.end(); I != E; ++I) {
-      std::string p = *I;
+    for (StringSet<>::iterator i = GVStubs.begin(), e = GVStubs.end();
+         i != e; ++i) {
+      std::string p = i->getKeyData();
       printSuffixedName(p, "$non_lazy_ptr");
       O << ":\n";
-      O << "\t.indirect_symbol " << *I << '\n';
+      O << "\t.indirect_symbol " << p << '\n';
       if (isPPC64)
         O << "\t.quad\t0\n";
       else
@@ -1088,8 +1109,25 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
     }
   }
 
+  if (!HiddenGVStubs.empty()) {
+    SwitchToSection(TAI->getDataSection());
+    for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end();
+         i != e; ++i) {
+      std::string p = i->getKeyData();
+      EmitAlignment(isPPC64 ? 3 : 2);
+      printSuffixedName(p, "$non_lazy_ptr");
+      O << ":\n";
+      if (isPPC64)
+        O << "\t.quad\t";
+      else
+        O << "\t.long\t";
+      O << p << '\n';
+    }
+  }
+
+
   // 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
@@ -1107,7 +1145,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
 /// for a MachineFunction to the given output stream, in a format that the
 /// Darwin assembler can deal with.
 ///
-FunctionPass *llvm::createPPCAsmPrinterPass(std::ostream &o,
+FunctionPass *llvm::createPPCAsmPrinterPass(raw_ostream &o,
                                             PPCTargetMachine &tm) {
   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
 
@@ -1125,3 +1163,6 @@ namespace {
     }
   } Registrator;
 }
+
+extern "C" int PowerPCAsmPrinterForceLink;
+int PowerPCAsmPrinterForceLink = 0;