Rename PaddedSize to AllocSize, in the hope that this
[oota-llvm.git] / lib / Target / X86 / AsmPrinter / X86ATTAsmPrinter.cpp
index 57db93387f0e2f77dd7b18f7ffd82b1a6abd5b0f..c88af21784c34eb3705469607a141995d7ea4452 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/Type.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/CodeGen/DwarfWriter.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/raw_ostream.h"
@@ -75,7 +76,7 @@ static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
       Ty = cast<PointerType>(Ty)->getElementType();
 
     // Size should be aligned to DWORD boundary
-    Size += ((TD->getABITypeSize(Ty) + 3)/4)*4;
+    Size += ((TD->getTypeAllocSize(Ty) + 3)/4)*4;
   }
 
   // We're not supporting tooooo huge arguments :)
@@ -84,7 +85,7 @@ static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
 }
 
 /// 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)
@@ -153,12 +154,13 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
 
   SwitchToSection(TAI->SectionForGlobal(F));
 
-  unsigned FnAlign = OptimizeForSize ? 1 : 4;
-  if (!F->isDeclaration() && F->hasNote(Attribute::OptimizeForSize))
+  unsigned FnAlign = 4;
+  if (F->hasFnAttr(Attribute::OptimizeForSize))
     FnAlign = 1;
   switch (F->getLinkage()) {
   default: assert(0 && "Unknown linkage type!");
   case Function::InternalLinkage:  // Symbols default to internal.
+  case Function::PrivateLinkage:
     EmitAlignment(FnAlign, F);
     break;
   case Function::DLLExportLinkage:
@@ -166,8 +168,10 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
     EmitAlignment(FnAlign, F);
     O << "\t.globl\t" << CurrentFnName << '\n';
     break;
-  case Function::LinkOnceLinkage:
-  case Function::WeakLinkage:
+  case Function::LinkOnceAnyLinkage:
+  case Function::LinkOnceODRLinkage:
+  case Function::WeakAnyLinkage:
+  case Function::WeakODRLinkage:
     EmitAlignment(FnAlign, F);
     if (Subtarget->isTargetDarwin()) {
       O << "\t.globl\t" << CurrentFnName << '\n';
@@ -188,7 +192,7 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
   else if (Subtarget->isTargetCygMing()) {
     O << "\t.def\t " << CurrentFnName
       << ";\t.scl\t" <<
-      (F->getLinkage() == Function::InternalLinkage ? COFF::C_STAT : COFF::C_EXT)
+      (F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT)
       << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
       << ";\t.endef\n";
   }
@@ -196,8 +200,7 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
   O << CurrentFnName << ":\n";
   // Add some workaround for linkonce linkage on Cygwin\MinGW
   if (Subtarget->isTargetCygMing() &&
-      (F->getLinkage() == Function::LinkOnceLinkage ||
-       F->getLinkage() == Function::WeakLinkage))
+      (F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
     O << "Lllvm$workaround$fake$stub$" << CurrentFnName << ":\n";
 }
 
@@ -206,6 +209,7 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
 ///
 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   const Function *F = MF.getFunction();
+  this->MF = &MF;
   unsigned CC = F->getCallingConv();
 
   SetupMachineFunction(MF);
@@ -227,15 +231,18 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Emit pre-function debug and/or EH information.
   if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
-    DW.BeginFunction(&MF);
+    DW->BeginFunction(&MF);
 
   // Print out code for the function.
   bool hasAnyRealCode = false;
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I) {
     // Print a label for the basic block.
-    if (!I->pred_empty()) {
-      printBasicBlockLabel(I, true, true);
+    if (!VerboseAsm && (I->pred_empty() || I->isOnlyReachableByFallthrough())) {
+      // This is an entry block or a block that's only reachable via a
+      // fallthrough edge. In non-VerboseAsm mode, don't print the label.
+    } else {
+      printBasicBlockLabel(I, true, true, VerboseAsm);
       O << '\n';
     }
     for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
@@ -260,11 +267,13 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Emit post-function debug information.
   if (TAI->doesSupportDebugInformation())
-    DW.EndFunction();
+    DW->EndFunction(&MF);
 
   // Print out jump tables referenced by the function.
   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
 
+  O.flush();
+
   // We didn't modify anything.
   return false;
 }
@@ -302,13 +311,14 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
   }
 
   case MachineOperand::MO_Immediate:
-    if (!Modifier ||
-        (strcmp(Modifier, "debug") && strcmp(Modifier, "mem")))
+    if (!Modifier || (strcmp(Modifier, "debug") &&
+                      strcmp(Modifier, "mem") &&
+                      strcmp(Modifier, "call")))
       O << '$';
     O << MO.getImm();
     return;
   case MachineOperand::MO_MachineBasicBlock:
-    printBasicBlockLabel(MO.getMBB());
+    printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm);
     return;
   case MachineOperand::MO_JumpTableIndex: {
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
@@ -342,11 +352,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
         O << "@GOTOFF";
     }
 
-    int Offset = MO.getOffset();
-    if (Offset > 0)
-      O << '+' << Offset;
-    else if (Offset < 0)
-      O << Offset;
+    printOffset(MO.getOffset());
 
     if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
       O << "(%rip)";
@@ -393,6 +399,14 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
             FnStubs.insert(Name);
             printSuffixedName(Name, "$stub");
           }
+        } else if (GV->hasHiddenVisibility()) {
+          if (!GV->isDeclaration() && !GV->hasCommonLinkage())
+            // Definition is not definitely in the current translation unit.
+            O << Name;
+          else {
+            HiddenGVStubs.insert(Name);
+            printSuffixedName(Name, "$non_lazy_ptr");
+          }
         } else {
           GVStubs.insert(Name);
           printSuffixedName(Name, "$non_lazy_ptr");
@@ -415,7 +429,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
         if (shouldPrintPLT(TM, Subtarget)) {
           // Assemble call via PLT for externally visible symbols
           if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
-              !GV->hasInternalLinkage())
+              !GV->hasLocalLinkage())
             O << "@PLT";
         }
         if (Subtarget->isTargetCygMing() && GV->isDeclaration())
@@ -427,34 +441,50 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
     if (GV->hasExternalWeakLinkage())
       ExtWeakSymbols.insert(GV);
 
-    int Offset = MO.getOffset();
-    if (Offset > 0)
-      O << '+' << Offset;
-    else if (Offset < 0)
-      O << Offset;
+    printOffset(MO.getOffset());
 
     if (isThreadLocal) {
-      if (TM.getRelocationModel() == Reloc::PIC_ || Subtarget->is64Bit())
-        O << "@TLSGD"; // general dynamic TLS model
-      else
-        if (GV->isDeclaration())
-          O << "@INDNTPOFF"; // initial exec TLS model
+      TLSModel::Model model = getTLSModel(GVar, TM.getRelocationModel());
+      switch (model) {
+      case TLSModel::GeneralDynamic:
+        O << "@TLSGD";
+        break;
+      case TLSModel::LocalDynamic:
+        // O << "@TLSLD"; // local dynamic not implemented
+       O << "@TLSGD";
+        break;
+      case TLSModel::InitialExec:
+        if (Subtarget->is64Bit()) {
+          assert (!NotRIPRel);
+          O << "@GOTTPOFF(%rip)";
+        } else {
+          O << "@INDNTPOFF";
+        }
+        break;
+      case TLSModel::LocalExec:
+        if (Subtarget->is64Bit())
+          O << "@TPOFF";
         else
-          O << "@NTPOFF"; // local exec TLS model
+         O << "@NTPOFF";
+        break;
+      default:
+        assert (0 && "Unknown TLS model");
+      }
     } else if (isMemOp) {
       if (shouldPrintGOT(TM, Subtarget)) {
         if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
           O << "@GOT";
         else
           O << "@GOTOFF";
-      } else if (Subtarget->isPICStyleRIPRel() && !NotRIPRel &&
-                 TM.getRelocationModel() != Reloc::Static) {
-        if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
-          O << "@GOTPCREL";
-
-        if (needCloseParen) {
-          needCloseParen = false;
-          O << ')';
+      } else if (Subtarget->isPICStyleRIPRel() && !NotRIPRel) {
+        if (TM.getRelocationModel() != Reloc::Static) {
+          if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
+            O << "@GOTPCREL";
+
+          if (needCloseParen) {
+            needCloseParen = false;
+            O << ')';
+          }
         }
 
         // Use rip when possible to reduce code size, except when
@@ -471,6 +501,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
   }
   case MachineOperand::MO_ExternalSymbol: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
+    bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
     bool needCloseParen = false;
     std::string Name(TAI->getGlobalPrefix());
     Name += MO.getSymbolName();
@@ -481,7 +512,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
       printSuffixedName(Name, "$stub");
       return;
     }
-    if (!isCallOp)
+    if (!isMemOp && !isCallOp)
       O << '$';
     else if (Name[0] == '$') {
       // The name begins with a dollar-sign. In order to avoid having it look
@@ -538,17 +569,18 @@ void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
   }
 }
 
-void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
-                                         const char *Modifier){
-  assert(isMem(MI, Op) && "Invalid memory reference!");
+void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
+                                            const char *Modifier,
+                                            bool NotRIPRel) {
   MachineOperand BaseReg  = MI->getOperand(Op);
   MachineOperand IndexReg = MI->getOperand(Op+2);
   const MachineOperand &DispSpec = MI->getOperand(Op+3);
 
-  bool NotRIPRel = IndexReg.getReg() || BaseReg.getReg();
-  if (DispSpec.isGlobalAddress() ||
-      DispSpec.isConstantPoolIndex() ||
-      DispSpec.isJumpTableIndex()) {
+  NotRIPRel |= IndexReg.getReg() || BaseReg.getReg();
+  if (DispSpec.isGlobal() ||
+      DispSpec.isCPI() ||
+      DispSpec.isJTI() ||
+      DispSpec.isSymbol()) {
     printOperand(MI, Op+3, "mem", NotRIPRel);
   } else {
     int DispVal = DispSpec.getImm();
@@ -583,6 +615,17 @@ void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
   }
 }
 
+void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
+                                         const char *Modifier, bool NotRIPRel){
+  assert(isMem(MI, Op) && "Invalid memory reference!");
+  MachineOperand Segment = MI->getOperand(Op+4);
+  if (Segment.getReg()) {
+      printOperand(MI, Op+4, Modifier);
+      O << ':';
+    }
+  printLeaMemReference(MI, Op, Modifier, NotRIPRel);
+}
+
 void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid,
                                            const MachineBasicBlock *MBB) const {
   if (!TAI->getSetDirective())
@@ -668,20 +711,20 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
     switch (ExtraCode[0]) {
     default: return true;  // Unknown modifier.
     case 'c': // Don't print "$" before a global var name or constant.
-      printOperand(MI, OpNo, "mem");
+      printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
       return false;
     case 'b': // Print QImode register
     case 'h': // Print QImode high register
     case 'w': // Print HImode register
     case 'k': // Print SImode register
     case 'q': // Print DImode register
-      if (MI->getOperand(OpNo).isRegister())
+      if (MI->getOperand(OpNo).isReg())
         return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]);
       printOperand(MI, OpNo);
       return false;
 
     case 'P': // Don't print @PLT, but do print as memory.
-      printOperand(MI, OpNo, "mem");
+      printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
       return false;
     }
   }
@@ -706,14 +749,17 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
     case 'q': // Print SImode register
       // These only apply to registers, ignore on mem.
       break;
+    case 'P': // Don't print @PLT, but do print as memory.
+      printMemReference(MI, OpNo, "mem", /*NotRIPRel=*/true);
+      return false;
     }
   }
   printMemReference(MI, OpNo);
   return false;
 }
 
-/// printMachineInstruction -- Print out a single X86 LLVM instruction
-/// MI in AT&T syntax to the current output stream.
+/// printMachineInstruction -- Print out a single X86 LLVM instruction MI in
+/// AT&T syntax to the current output stream.
 ///
 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
@@ -724,10 +770,6 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
 
 /// doInitialization
 bool X86ATTAsmPrinter::doInitialization(Module &M) {
-  if (TAI->doesSupportDebugInformation()) {
-    // Emit initial debug information.
-    DW.BeginModule(&M);
-  }
 
   bool Result = AsmPrinter::doInitialization(M);
 
@@ -735,8 +777,9 @@ bool X86ATTAsmPrinter::doInitialization(Module &M) {
     // Let PassManager know we need debug information and relay
     // the MachineModuleInfo address on to DwarfWriter.
     // AsmPrinter::doInitialization did this analysis.
-    MMI = getAnalysisToUpdate<MachineModuleInfo>();
-    DW.SetModuleInfo(MMI);
+    MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+    DW = getAnalysisIfAvailable<DwarfWriter>();
+    DW->BeginModule(&M, MMI, O, this, TAI);
   }
 
   // Darwin wants symbols to be quoted if they have complex names.
@@ -768,7 +811,7 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
   std::string name = Mang->getValueName(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);
 
   printVisibility(name, GVar->getVisibility());
@@ -778,7 +821,9 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
 
   SwitchToSection(TAI->SectionForGlobal(GVar));
 
-  if (C->isNullValue() && !GVar->hasSection()) {
+  if (C->isNullValue() && !GVar->hasSection() &&
+      !(Subtarget->isTargetDarwin() &&
+        TAI->SectionKindForGlobal(GVar) == SectionKind::RODataMergeStr)) {
     // FIXME: This seems to be pretty darwin-specific
     if (GVar->hasExternalLinkage()) {
       if (const char *Directive = TAI->getZeroFillDirective()) {
@@ -790,11 +835,11 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
     }
 
     if (!GVar->isThreadLocal() &&
-        (GVar->hasInternalLinkage() || GVar->isWeakForLinker())) {
+        (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
       if (TAI->getLCOMMDirective() != NULL) {
-        if (GVar->hasInternalLinkage()) {
+        if (GVar->hasLocalLinkage()) {
           O << TAI->getLCOMMDirective() << name << ',' << Size;
           if (Subtarget->isTargetDarwin())
             O << ',' << Align;
@@ -802,8 +847,11 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
           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;
@@ -814,15 +862,17 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
         }
       } else {
         if (!Subtarget->isTargetCygMing()) {
-          if (GVar->hasInternalLinkage())
+          if (GVar->hasLocalLinkage())
             O << "\t.local\t" << name << '\n';
         }
         O << TAI->getCOMMDirective()  << name << ',' << Size;
         if (TAI->getCOMMDirectiveTakesAlignment())
           O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
       }
-      O << "\t\t" << TAI->getCommentString() << ' ';
-      PrintUnmangledNameSafely(GVar, O);
+      if (VerboseAsm) {
+        O << "\t\t" << TAI->getCommentString() << ' ';
+        PrintUnmangledNameSafely(GVar, O);
+      }
       O << '\n';
       return;
     }
@@ -830,8 +880,10 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
 
   switch (GVar->getLinkage()) {
   case GlobalValue::CommonLinkage:
-  case GlobalValue::LinkOnceLinkage:
-  case GlobalValue::WeakLinkage:
+  case GlobalValue::LinkOnceAnyLinkage:
+  case GlobalValue::LinkOnceODRLinkage:
+  case GlobalValue::WeakAnyLinkage:
+  case GlobalValue::WeakODRLinkage:
     if (Subtarget->isTargetDarwin()) {
       O << "\t.globl " << name << '\n'
         << TAI->getWeakDefDirective() << name << '\n';
@@ -850,6 +902,7 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
     // If external or appending, declare as a global symbol
     O << "\t.globl " << name << '\n';
     // FALL THROUGH
+  case GlobalValue::PrivateLinkage:
   case GlobalValue::InternalLinkage:
      break;
   default:
@@ -857,18 +910,15 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
   }
 
   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';
   if (TAI->hasDotTypeDotSizeDirective())
     O << "\t.size\t" << name << ", " << Size << '\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);
-
   EmitGlobalConstant(C);
 }
 
@@ -881,6 +931,15 @@ void X86ATTAsmPrinter::printGVStub(const char *GV, const char *Prefix) {
   O << GV << "\n\t.long\t0\n";
 }
 
+/// printHiddenGVStub - Print stub for a hidden global value.
+///
+void X86ATTAsmPrinter::printHiddenGVStub(const char *GV, const char *Prefix) {
+  EmitAlignment(2);
+  printSuffixedName(GV, "$non_lazy_ptr", Prefix);
+  if (Prefix) O << Prefix;
+  O << ":\n" << TAI->getData32bitsDirective() << GV << '\n';
+}
+
 
 bool X86ATTAsmPrinter::doFinalization(Module &M) {
   // Print out module-level global variables here.
@@ -890,6 +949,25 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
 
     if (I->hasDLLExportLinkage())
       DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),""));
+
+    // If the global is a extern weak symbol, remember to emit the weak
+    // reference!
+    // FIXME: This is rather hacky, since we'll emit references to ALL weak stuff,
+    // not used. But currently it's the only way to deal with extern weak
+    // initializers hidden deep inside constant expressions.
+    if (I->hasExternalWeakLinkage())
+      ExtWeakSymbols.insert(I);
+  }
+
+  for (Module::const_iterator I = M.begin(), E = M.end();
+       I != E; ++I) {
+    // If the global is a extern weak symbol, remember to emit the weak
+    // reference!
+    // FIXME: This is rather hacky, since we'll emit references to ALL weak stuff,
+    // not used. But currently it's the only way to deal with extern weak
+    // initializers hidden deep inside constant expressions.
+    if (I->hasExternalWeakLinkage())
+      ExtWeakSymbols.insert(I);
   }
 
   // Output linker support code for dllexported globals
@@ -914,9 +992,8 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
     SwitchToDataSection("");
 
     // Output stubs for dynamically-linked functions
-    unsigned j = 1;
     for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
-         i != e; ++i, ++j) {
+         i != e; ++i) {
       SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs,"
                           "self_modifying_code+pure_instructions,5", 0);
       const char *p = i->getKeyData();
@@ -955,8 +1032,16 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
          i != e; ++i)
       printGVStub(i->getKeyData());
 
+    if (!HiddenGVStubs.empty()) {
+      SwitchToSection(TAI->getDataSection());
+      for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end();
+           i != e; ++i)
+        printHiddenGVStub(i->getKeyData());
+    }
+
     // Emit final debug information.
-    DW.EndModule();
+    DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
+    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
@@ -975,10 +1060,12 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
     }
 
     // Emit final debug information.
-    DW.EndModule();
+    DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
+    DW->EndModule();
   } else if (Subtarget->isTargetELF()) {
     // Emit final debug information.
-    DW.EndModule();
+    DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
+    DW->EndModule();
   }
 
   return AsmPrinter::doFinalization(M);