llvm_unreachable->llvm_unreachable(0), LLVM_UNREACHABLE->llvm_unreachable.
[oota-llvm.git] / lib / Target / PowerPC / AsmPrinter / PPCAsmPrinter.cpp
index 3ed7265840147f263d12f1713b57d29458201843..fddc1c2993ff659fbc7e71f4b0ef9571d4bb312a 100644 (file)
@@ -24,6 +24,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
+#include "llvm/MDNode.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/DwarfWriter.h"
@@ -35,6 +36,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetAsmInfo.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;
+  class VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter {
+  protected:
+    StringSet<> FnStubs, GVStubs, HiddenGVStubs;
     const PPCSubtarget &Subtarget;
-
-    PPCAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
-      : AsmPrinter(O, TM, T), Subtarget(TM.getSubtarget<PPCSubtarget>()) {
-    }
+  public:
+    explicit PPCAsmPrinter(raw_ostream &O, TargetMachine &TM,
+                           const TargetAsmInfo *T, bool V)
+      : AsmPrinter(O, TM, T, V),
+        Subtarget(TM.getSubtarget<PPCSubtarget>()) {}
 
     virtual const char *getPassName() const {
       return "PowerPC Assembly Printer";
@@ -67,7 +71,7 @@ namespace {
 
     unsigned enumRegToMachineReg(unsigned enumReg) {
       switch (enumReg) {
-      default: assert(0 && "Unhandled register!"); break;
+      default: llvm_unreachable("Unhandled register!");
       case PPC::CR0:  return  0;
       case PPC::CR1:  return  1;
       case PPC::CR2:  return  2;
@@ -77,7 +81,7 @@ namespace {
       case PPC::CR6:  return  6;
       case PPC::CR7:  return  7;
       }
-      abort();
+      llvm_unreachable(0);
     }
 
     /// printInstruction - This method is automatically generated by tablegen
@@ -185,14 +189,11 @@ namespace {
       if (TM.getRelocationModel() != Reloc::Static) {
         if (MO.getType() == MachineOperand::MO_GlobalAddress) {
           GlobalValue *GV = MO.getGlobal();
-          if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
-                GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
+          if (GV->isDeclaration() || GV->isWeakForLinker()) {
             // Dynamically-resolved functions need a stub for the function.
             std::string Name = Mang->getValueName(GV);
             FnStubs.insert(Name);
             printSuffixedName(Name, "$stub");
-            if (GV->hasExternalWeakLinkage())
-              ExtWeakSymbols.insert(GV);
             return;
           }
         }
@@ -291,27 +292,23 @@ namespace {
   };
 
   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
-  struct VISIBILITY_HIDDEN PPCLinuxAsmPrinter : public PPCAsmPrinter {
-
-    DwarfWriter DW;
-    MachineModuleInfo *MMI;
-
-    PPCLinuxAsmPrinter(raw_ostream &O, PPCTargetMachine &TM,
-                    const TargetAsmInfo *T)
-      : PPCAsmPrinter(O, TM, T), DW(O, this, T), MMI(0) {
-    }
+  class VISIBILITY_HIDDEN PPCLinuxAsmPrinter : public PPCAsmPrinter {
+  public:
+    explicit PPCLinuxAsmPrinter(raw_ostream &O, PPCTargetMachine &TM,
+                                const TargetAsmInfo *T, bool V)
+      : PPCAsmPrinter(O, TM, T, V){}
 
     virtual const char *getPassName() const {
       return "Linux PPC Assembly Printer";
     }
 
     bool runOnMachineFunction(MachineFunction &F);
-    bool doInitialization(Module &M);
     bool doFinalization(Module &M);
 
     void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesAll();
       AU.addRequired<MachineModuleInfo>();
+      AU.addRequired<DwarfWriter>();
       PPCAsmPrinter::getAnalysisUsage(AU);
     }
 
@@ -320,15 +317,12 @@ namespace {
 
   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
   /// OS X
-  struct VISIBILITY_HIDDEN PPCDarwinAsmPrinter : public PPCAsmPrinter {
-
-    DwarfWriter DW;
-    MachineModuleInfo *MMI;
-
-    PPCDarwinAsmPrinter(raw_ostream &O, PPCTargetMachine &TM,
-                        const TargetAsmInfo *T)
-      : PPCAsmPrinter(O, TM, T), DW(O, this, T), MMI(0) {
-    }
+  class VISIBILITY_HIDDEN PPCDarwinAsmPrinter : public PPCAsmPrinter {
+    raw_ostream &OS;
+  public:
+    explicit PPCDarwinAsmPrinter(raw_ostream &O, PPCTargetMachine &TM,
+                                 const TargetAsmInfo *T, bool V)
+      : PPCAsmPrinter(O, TM, T, V), OS(O) {}
 
     virtual const char *getPassName() const {
       return "Darwin PPC Assembly Printer";
@@ -341,6 +335,7 @@ namespace {
     void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesAll();
       AU.addRequired<MachineModuleInfo>();
+      AU.addRequired<DwarfWriter>();
       PPCAsmPrinter::getAnalysisUsage(AU);
     }
 
@@ -354,9 +349,7 @@ namespace {
 void PPCAsmPrinter::printOp(const MachineOperand &MO) {
   switch (MO.getType()) {
   case MachineOperand::MO_Immediate:
-    cerr << "printOp() does not handle immediate values\n";
-    abort();
-    return;
+    llvm_unreachable("printOp() does not handle immediate values");
 
   case MachineOperand::MO_MachineBasicBlock:
     printBasicBlockLabel(MO.getMBB());
@@ -387,21 +380,25 @@ 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->hasExternalWeakLinkage())
-          ExtWeakSymbols.insert(GV);
+      if (GV->isDeclaration() || GV->isWeakForLinker()) {
+        if (GV->hasHiddenVisibility()) {
+          if (GV->isDeclaration() || GV->hasCommonLinkage() ||
+              GV->hasAvailableExternallyLinkage()) {
+            HiddenGVStubs.insert(Name);
+            printSuffixedName(Name, "$non_lazy_ptr");
+          } else {
+            O << Name;
+          }
+        } else {
+          GVStubs.insert(Name);
+          printSuffixedName(Name, "$non_lazy_ptr");
+        }
         return;
       }
     }
     O << Name;
 
     printOffset(MO.getOffset());
-
-    if (GV->hasExternalWeakLinkage())
-      ExtWeakSymbols.insert(GV);
     return;
   }
 
@@ -414,9 +411,13 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
 /// EmitExternalGlobal - In this case we need to use the indirect symbol.
 ///
 void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) {
-  std::string Name = getGlobalLinkName(GV);
+  std::string Name;
+  getGlobalLinkName(GV, Name);
   if (TM.getRelocationModel() != Reloc::Static) {
-    GVStubs.insert(Name);
+    if (GV->hasHiddenVisibility())
+      HiddenGVStubs.insert(Name);
+    else
+      GVStubs.insert(Name);
     printSuffixedName(Name, "$non_lazy_ptr");
     return;
   }
@@ -550,15 +551,14 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   if (printInstruction(MI))
     return; // Printer was automatically generated
 
-  assert(0 && "Unhandled instruction in asm writer!");
-  abort();
-  return;
+  llvm_unreachable("Unhandled instruction in asm writer!");
 }
 
 /// runOnMachineFunction - This uses the printMachineInstruction()
 /// method to print assembly for each instruction.
 ///
 bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+  this->MF = &MF;
 
   SetupMachineFunction(MF);
   O << "\n\n";
@@ -571,15 +571,18 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   SwitchToSection(TAI->SectionForGlobal(F));
 
   switch (F->getLinkage()) {
-  default: assert(0 && "Unknown linkage type!");
+  default: llvm_unreachable("Unknown linkage type!");
+  case Function::PrivateLinkage:
   case Function::InternalLinkage:  // Symbols default to internal.
     break;
   case Function::ExternalLinkage:
     O << "\t.global\t" << CurrentFnName << '\n'
       << "\t.type\t" << CurrentFnName << ", @function\n";
     break;
-  case Function::WeakLinkage:
-  case Function::LinkOnceLinkage:
+  case Function::WeakAnyLinkage:
+  case Function::WeakODRLinkage:
+  case Function::LinkOnceAnyLinkage:
+  case Function::LinkOnceODRLinkage:
     O << "\t.global\t" << CurrentFnName << '\n';
     O << "\t.weak\t" << CurrentFnName << '\n';
     break;
@@ -587,11 +590,11 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   printVisibility(CurrentFnName, F->getVisibility());
 
-  EmitAlignment(2, F);
+  EmitAlignment(MF.getAlignment(), F);
   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();
@@ -616,7 +619,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   SwitchToSection(TAI->SectionForGlobal(F));
 
   // Emit post-function debug information.
-  DW.EndFunction(&MF);
+  DW->EndFunction(&MF);
 
   O.flush();
 
@@ -624,27 +627,8 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   return false;
 }
 
-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>();
-  assert(MMI);
-  DW.SetModuleInfo(MMI);
-
-  // GNU as handles section names wrapped in quotes
-  Mang->setUseQuotes(true);
-
-  SwitchToSection(TAI->getTextSection());
-
-  return Result;
-}
-
 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
-/// Don't print things like \n or \0.
+/// Don't print things like \\n or \\0.
 static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
        Name != E; ++Name)
@@ -667,16 +651,18 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
   printVisibility(name, GVar->getVisibility());
 
   Constant *C = GVar->getInitializer();
+  if (isa<MDNode>(C) || isa<MDString>(C))
+    return;
   const Type *Type = C->getType();
-  unsigned Size = TD->getABITypeSize(Type);
+  unsigned Size = TD->getTypeAllocSize(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->isWeakForLinker())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
       if (GVar->hasExternalLinkage()) {
@@ -684,20 +670,25 @@ 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;
       }
-      O << "\t\t" << TAI->getCommentString() << " '";
-      PrintUnmangledNameSafely(GVar, O);
-      O << "'\n";
+      if (VerboseAsm) {
+        O << "\t\t" << TAI->getCommentString() << " '";
+        PrintUnmangledNameSafely(GVar, O);
+        O << "'";
+      }
+      O << '\n';
       return;
   }
 
   switch (GVar->getLinkage()) {
-   case GlobalValue::LinkOnceLinkage:
-   case GlobalValue::WeakLinkage:
+   case GlobalValue::LinkOnceAnyLinkage:
+   case GlobalValue::LinkOnceODRLinkage:
+   case GlobalValue::WeakAnyLinkage:
+   case GlobalValue::WeakODRLinkage:
    case GlobalValue::CommonLinkage:
     O << "\t.global " << name << '\n'
       << "\t.type " << name << ", @object\n"
@@ -712,22 +703,20 @@ 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!";
-    abort();
+    llvm_unreachable("Unknown linkage type!");
   }
 
   EmitAlignment(Align, GVar);
-  O << name << ":\t\t\t\t" << TAI->getCommentString() << " '";
-  PrintUnmangledNameSafely(GVar, O);
-  O << "'\n";
-
-  // If the initializer is a extern weak symbol, remember to emit the weak
-  // reference!
-  if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
-    if (GV->hasExternalWeakLinkage())
-      ExtWeakSymbols.insert(GV);
+  O << name << ":";
+  if (VerboseAsm) {
+    O << "\t\t\t\t" << TAI->getCommentString() << " '";
+    PrintUnmangledNameSafely(GVar, O);
+    O << "'";
+  }
+  O << '\n';
 
   EmitGlobalConstant(C);
   O << '\n';
@@ -739,11 +728,6 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
        I != E; ++I)
     printModuleLevelGV(I);
 
-  // TODO
-
-  // Emit initial debug information.
-  DW.EndModule();
-
   return AsmPrinter::doFinalization(M);
 }
 
@@ -751,6 +735,8 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
 /// method to print assembly for each instruction.
 ///
 bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+  this->MF = &MF;
+
   SetupMachineFunction(MF);
   O << "\n\n";
 
@@ -762,14 +748,17 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   SwitchToSection(TAI->SectionForGlobal(F));
 
   switch (F->getLinkage()) {
-  default: assert(0 && "Unknown linkage type!");
+  default: llvm_unreachable("Unknown linkage type!");
+  case Function::PrivateLinkage:
   case Function::InternalLinkage:  // Symbols default to internal.
     break;
   case Function::ExternalLinkage:
     O << "\t.globl\t" << CurrentFnName << '\n';
     break;
-  case Function::WeakLinkage:
-  case Function::LinkOnceLinkage:
+  case Function::WeakAnyLinkage:
+  case Function::WeakODRLinkage:
+  case Function::LinkOnceAnyLinkage:
+  case Function::LinkOnceODRLinkage:
     O << "\t.globl\t" << CurrentFnName << '\n';
     O << "\t.weak_definition\t" << CurrentFnName << '\n';
     break;
@@ -777,11 +766,11 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   printVisibility(CurrentFnName, F->getVisibility());
 
-  EmitAlignment(F->hasFnAttr(Attribute::OptimizeForSize) ? 2 : 4, F);
+  EmitAlignment(MF.getAlignment(), 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
@@ -796,7 +785,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
        I != E; ++I) {
     // Print a label for the basic block.
     if (I != MF.begin()) {
-      printBasicBlockLabel(I, true, true);
+      printBasicBlockLabel(I, true, true, VerboseAsm);
       O << '\n';
     }
     for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
@@ -810,7 +799,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;
@@ -841,18 +830,7 @@ bool PPCDarwinAsmPrinter::doInitialization(Module &M) {
   O << "\t.machine " << CPUDirectives[Directive] << '\n';
 
   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>();
   assert(MMI);
-  DW.SetModuleInfo(MMI);
-
-  // Darwin wants symbols to be quoted if they have complex names.
-  Mang->setUseQuotes(true);
 
   // Prime text sections so they are adjacent.  This reduces the likelihood a
   // large data or debug section causes a branch to exceed 16M limit.
@@ -893,29 +871,33 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
 
   Constant *C = GVar->getInitializer();
   const Type *Type = C->getType();
-  unsigned Size = TD->getABITypeSize(Type);
+  unsigned Size = TD->getTypeAllocSize(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->isWeakForLinker()) &&
+      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'
         << TAI->getWeakDefDirective() << name << '\n';
       EmitAlignment(Align, GVar);
-      O << name << ":\t\t\t\t" << TAI->getCommentString() << " ";
-      PrintUnmangledNameSafely(GVar, O);
+      O << name << ":";
+      if (VerboseAsm) {
+        O << "\t\t\t\t" << TAI->getCommentString() << " ";
+        PrintUnmangledNameSafely(GVar, O);
+      }
       O << '\n';
       EmitGlobalConstant(C);
       return;
@@ -925,15 +907,20 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
       if (Subtarget.isDarwin9())
         O << ',' << Align;
     }
-    O << "\t\t" << TAI->getCommentString() << " '";
-    PrintUnmangledNameSafely(GVar, O);
-    O << "'\n";
+    if (VerboseAsm) {
+      O << "\t\t" << TAI->getCommentString() << " '";
+      PrintUnmangledNameSafely(GVar, O);
+      O << "'";
+    }
+    O << '\n';
     return;
   }
 
   switch (GVar->getLinkage()) {
-   case GlobalValue::LinkOnceLinkage:
-   case GlobalValue::WeakLinkage:
+   case GlobalValue::LinkOnceAnyLinkage:
+   case GlobalValue::LinkOnceODRLinkage:
+   case GlobalValue::WeakAnyLinkage:
+   case GlobalValue::WeakODRLinkage:
    case GlobalValue::CommonLinkage:
     O << "\t.globl " << name << '\n'
       << "\t.weak_definition " << name << '\n';
@@ -946,22 +933,20 @@ 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!";
-    abort();
+    llvm_unreachable("Unknown linkage type!");
   }
 
   EmitAlignment(Align, GVar);
-  O << name << ":\t\t\t\t" << TAI->getCommentString() << " '";
-  PrintUnmangledNameSafely(GVar, O);
-  O << "'\n";
-
-  // If the initializer is a extern weak symbol, remember to emit the weak
-  // reference!
-  if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
-    if (GV->hasExternalWeakLinkage())
-      ExtWeakSymbols.insert(GV);
+  O << name << ":";
+  if (VerboseAsm) {
+    O << "\t\t\t\t" << TAI->getCommentString() << " '";
+    PrintUnmangledNameSafely(GVar, O);
+    O << "'";
+  }
+  O << '\n';
 
   EmitGlobalConstant(C);
   O << '\n';
@@ -979,51 +964,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";
@@ -1038,7 +1042,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
@@ -1051,8 +1055,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
   if (TAI->doesSupportExceptionHandling() && MMI) {
     // Add the (possibly multiple) personalities to the set of global values.
     // Only referenced functions get into the Personalities list.
-    const std::vector<Function *>& Personalities = MMI->getPersonalities();
-
+    const std::vector<Function *> &Personalities = MMI->getPersonalities();
     for (std::vector<Function *>::const_iterator I = Personalities.begin(),
            E = Personalities.end(); I != E; ++I)
       if (*I) GVStubs.insert("_" + (*I)->getName());
@@ -1061,12 +1064,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
@@ -1074,8 +1077,21 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
     }
   }
 
-  // Emit initial debug information.
-  DW.EndModule();
+  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';
+    }
+  }
 
   // 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
@@ -1094,13 +1110,14 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
 /// Darwin assembler can deal with.
 ///
 FunctionPass *llvm::createPPCAsmPrinterPass(raw_ostream &o,
-                                            PPCTargetMachine &tm) {
+                                            PPCTargetMachine &tm,
+                                            bool verbose) {
   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
 
   if (Subtarget->isDarwin()) {
-    return new PPCDarwinAsmPrinter(o, tm, tm.getTargetAsmInfo());
+    return new PPCDarwinAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose);
   } else {
-    return new PPCLinuxAsmPrinter(o, tm, tm.getTargetAsmInfo());
+    return new PPCLinuxAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose);
   }
 }
 
@@ -1114,3 +1131,6 @@ namespace {
 
 extern "C" int PowerPCAsmPrinterForceLink;
 int PowerPCAsmPrinterForceLink = 0;
+
+// Force static initialization.
+extern "C" void LLVMInitializePowerPCAsmPrinter() { }