Remove some overzealous checks that were rejecting
[oota-llvm.git] / lib / CodeGen / AsmPrinter / AsmPrinter.cpp
index 4d16c7b0f1adb8193f230de17af8ea70019c463c..018544150902066b594c91ec690e531e1752fd30 100644 (file)
 #include "llvm/DerivedTypes.h"
 #include "llvm/Constants.h"
 #include "llvm/Module.h"
-#include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/GCMetadataPrinter.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/Support/Mangler.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include <cerrno>
 using namespace llvm;
 
 char AsmPrinter::ID = 0;
-AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm,
+AsmPrinter::AsmPrinter(raw_ostream &o, TargetMachine &tm,
                        const TargetAsmInfo *T)
-  : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o),
+  : MachineFunctionPass(&ID), FunctionNumber(0), O(o),
     TM(tm), TAI(T), TRI(tm.getRegisterInfo()),
     IsInTextSection(false)
 {}
@@ -49,11 +47,6 @@ AsmPrinter::~AsmPrinter() {
                     E = GCMetadataPrinters.end(); I != E; ++I)
     delete I->second;
 }
-    
-std::string AsmPrinter::getSectionForFunction(const Function &F) const {
-  return TAI->getTextSection();
-}
-
 
 /// SwitchToTextSection - Switch to the specified text section of the executable
 /// if we are not already in it!
@@ -107,25 +100,51 @@ void AsmPrinter::SwitchToDataSection(const char *NewSection,
   IsInTextSection = false;
 }
 
+/// SwitchToSection - Switch to the specified section of the executable if we
+/// are not already in it!
+void AsmPrinter::SwitchToSection(const Section* NS) {
+  const std::string& NewSection = NS->getName();
+
+  // If we're already in this section, we're done.
+  if (CurrentSection == NewSection) return;
+
+  // Close the current section, if applicable.
+  if (TAI->getSectionEndDirectiveSuffix() && !CurrentSection.empty())
+    O << CurrentSection << TAI->getSectionEndDirectiveSuffix() << '\n';
+
+  // FIXME: Make CurrentSection a Section* in the future
+  CurrentSection = NewSection;
+  CurrentSection_ = NS;
+
+  if (!CurrentSection.empty()) {
+    // If section is named we need to switch into it via special '.section'
+    // directive and also append funky flags. Otherwise - section name is just
+    // some magic assembler directive.
+    if (NS->isNamed())
+      O << TAI->getSwitchToSectionDirective()
+        << CurrentSection
+        << TAI->getSectionFlags(NS->getFlags());
+    else
+      O << CurrentSection;
+    O << TAI->getDataSectionStartSuffix() << '\n';
+  }
+
+  IsInTextSection = (NS->getFlags() & SectionFlags::Code);
+}
 
 void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
   MachineFunctionPass::getAnalysisUsage(AU);
-  AU.addRequired<CollectorModuleMetadata>();
+  AU.addRequired<GCModuleInfo>();
 }
 
 bool AsmPrinter::doInitialization(Module &M) {
   Mang = new Mangler(M, TAI->getGlobalPrefix());
   
-  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
-  assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
-  for (CollectorModuleMetadata::iterator I = CMM->begin(),
-                                         E = CMM->end(); I != E; ++I)
-    if (GCMetadataPrinter *GCP = GetOrCreateGCPrinter(*I))
-      GCP->beginAssembly(O, *this, *TAI);
-<<<<<<< HEAD:lib/CodeGen/AsmPrinter.cpp
-=======
-
->>>>>>> Factor out asmprinters from collector interface.:lib/CodeGen/AsmPrinter.cpp
+  GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
+  for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
+    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
+      MP->beginAssembly(O, *this, *TAI);
   
   if (!M.getModuleInlineAsm().empty())
     O << TAI->getCommentString() << " Start of file scope inline assembly\n"
@@ -156,7 +175,7 @@ bool AsmPrinter::doFinalization(Module &M) {
 
   if (TAI->getSetDirective()) {
     if (!M.alias_empty())
-      SwitchToTextSection(TAI->getTextSection());
+      SwitchToSection(TAI->getTextSection());
 
     O << '\n';
     for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
@@ -166,7 +185,7 @@ bool AsmPrinter::doFinalization(Module &M) {
 
       const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal());
       Target = Mang->getValueName(GV);
-      
+
       if (I->hasExternalLinkage() || !TAI->getWeakRefDirective())
         O << "\t.globl\t" << Name << '\n';
       else if (I->hasWeakLinkage())
@@ -174,13 +193,7 @@ bool AsmPrinter::doFinalization(Module &M) {
       else if (!I->hasInternalLinkage())
         assert(0 && "Invalid alias linkage");
 
-      if (I->hasHiddenVisibility()) {
-        if (const char *Directive = TAI->getHiddenDirective())
-          O << Directive << Name << '\n';
-      } else if (I->hasProtectedVisibility()) {
-        if (const char *Directive = TAI->getProtectedDirective())
-          O << Directive << Name << '\n';
-      }
+      printVisibility(Name, I->getVisibility());
 
       O << TAI->getSetDirective() << ' ' << Name << ", " << Target << '\n';
 
@@ -196,12 +209,11 @@ bool AsmPrinter::doFinalization(Module &M) {
     }
   }
 
-  CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>();
-  assert(CMM && "AsmPrinter didn't require CollectorModuleMetadata?");
-  for (CollectorModuleMetadata::iterator I = CMM->end(),
-                                         E = CMM->begin(); I != E; )
-    if (GCMetadataPrinter *GCP = GetOrCreateGCPrinter(*--I))
-      GCP->finishAssembly(O, *this, *TAI);
+  GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
+  for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
+    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
+      MP->finishAssembly(O, *this, *TAI);
 
   // If we don't have any trampolines, then we don't require stack memory
   // to be executable. Some targets have a directive to declare this.
@@ -237,58 +249,50 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) {
   const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
   if (CP.empty()) return;
 
-  // Some targets require 4-, 8-, and 16- byte constant literals to be placed
-  // in special sections.
-  std::vector<std::pair<MachineConstantPoolEntry,unsigned> > FourByteCPs;
-  std::vector<std::pair<MachineConstantPoolEntry,unsigned> > EightByteCPs;
-  std::vector<std::pair<MachineConstantPoolEntry,unsigned> > SixteenByteCPs;
-  std::vector<std::pair<MachineConstantPoolEntry,unsigned> > OtherCPs;
-  std::vector<std::pair<MachineConstantPoolEntry,unsigned> > TargetCPs;
+  // Calculate sections for constant pool entries. We collect entries to go into
+  // the same section together to reduce amount of section switch statements.
+  typedef
+    std::multimap<const Section*,
+                  std::pair<MachineConstantPoolEntry, unsigned> > CPMap;
+  CPMap  CPs;
+  SmallPtrSet<const Section*, 5> Sections;
+
   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
     MachineConstantPoolEntry CPE = CP[i];
-    const Type *Ty = CPE.getType();
-    if (TAI->getFourByteConstantSection() &&
-        TM.getTargetData()->getABITypeSize(Ty) == 4)
-      FourByteCPs.push_back(std::make_pair(CPE, i));
-    else if (TAI->getEightByteConstantSection() &&
-             TM.getTargetData()->getABITypeSize(Ty) == 8)
-      EightByteCPs.push_back(std::make_pair(CPE, i));
-    else if (TAI->getSixteenByteConstantSection() &&
-             TM.getTargetData()->getABITypeSize(Ty) == 16)
-      SixteenByteCPs.push_back(std::make_pair(CPE, i));
-    else
-      OtherCPs.push_back(std::make_pair(CPE, i));
+    const Section* S = TAI->SelectSectionForMachineConst(CPE.getType());
+    CPs.insert(std::make_pair(S, std::make_pair(CPE, i)));
+    Sections.insert(S);
   }
 
-  unsigned Alignment = MCP->getConstantPoolAlignment();
-  EmitConstantPool(Alignment, TAI->getFourByteConstantSection(), FourByteCPs);
-  EmitConstantPool(Alignment, TAI->getEightByteConstantSection(), EightByteCPs);
-  EmitConstantPool(Alignment, TAI->getSixteenByteConstantSection(),
-                   SixteenByteCPs);
-  EmitConstantPool(Alignment, TAI->getConstantPoolSection(), OtherCPs);
-}
-
-void AsmPrinter::EmitConstantPool(unsigned Alignment, const char *Section,
-               std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP) {
-  if (CP.empty()) return;
+  // Now print stuff into the calculated sections.
+  for (SmallPtrSet<const Section*, 5>::iterator IS = Sections.begin(),
+         ES = Sections.end(); IS != ES; ++IS) {
+    SwitchToSection(*IS);
+    EmitAlignment(MCP->getConstantPoolAlignment());
+
+    std::pair<CPMap::iterator, CPMap::iterator> II = CPs.equal_range(*IS);
+    for (CPMap::iterator I = II.first, E = II.second; I != E; ++I) {
+      CPMap::iterator J = next(I);
+      MachineConstantPoolEntry Entry = I->second.first;
+      unsigned index = I->second.second;
+
+      O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
+        << index << ":\t\t\t\t\t";
+    // O << TAI->getCommentString() << ' ' << 
+    //      WriteTypeSymbolic(O, CP[i].first.getType(), 0);
+      O << '\n';
+      if (Entry.isMachineConstantPoolEntry())
+        EmitMachineConstantPoolValue(Entry.Val.MachineCPVal);
+      else
+        EmitGlobalConstant(Entry.Val.ConstVal);
 
-  SwitchToDataSection(Section);
-  EmitAlignment(Alignment);
-  for (unsigned i = 0, e = CP.size(); i != e; ++i) {
-    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
-      << CP[i].second << ":\t\t\t\t\t" << TAI->getCommentString() << ' ';
-    WriteTypeSymbolic(O, CP[i].first.getType(), 0) << '\n';
-    if (CP[i].first.isMachineConstantPoolEntry())
-      EmitMachineConstantPoolValue(CP[i].first.Val.MachineCPVal);
-     else
-      EmitGlobalConstant(CP[i].first.Val.ConstVal);
-    if (i != e-1) {
-      const Type *Ty = CP[i].first.getType();
-      unsigned EntSize =
-        TM.getTargetData()->getABITypeSize(Ty);
-      unsigned ValEnd = CP[i].first.getOffset() + EntSize;
       // Emit inter-object padding for alignment.
-      EmitZeros(CP[i+1].first.getOffset()-ValEnd);
+      if (J != E) {
+        const Type *Ty = Entry.getType();
+        unsigned EntSize = TM.getTargetData()->getABITypeSize(Ty);
+        unsigned ValEnd = Entry.getOffset() + EntSize;
+        EmitZeros(J->second.first.getOffset()-ValEnd);
+      }
     }
   }
 }
@@ -317,7 +321,7 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI,
     // function body itself, otherwise the label differences won't make sense.
     // We should also do if the section name is NULL or function is declared in
     // discardable section.
-    SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
+    SwitchToSection(TAI->SectionForGlobal(F));
   } else {
     SwitchToDataSection(JumpTableDataSection);
   }
@@ -431,8 +435,35 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
   return false;
 }
 
+/// findGlobalValue - if CV is an expression equivalent to a single
+/// global value, return that value.
+const GlobalValue * AsmPrinter::findGlobalValue(const Constant *CV) {
+  if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
+    return GV;
+  else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
+    const TargetData *TD = TM.getTargetData();
+    unsigned Opcode = CE->getOpcode();    
+    switch (Opcode) {
+    case Instruction::GetElementPtr: {
+      const Constant *ptrVal = CE->getOperand(0);
+      SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
+      if (TD->getIndexedOffset(ptrVal->getType(), &idxVec[0], idxVec.size()))
+        return 0;
+      return findGlobalValue(ptrVal);
+    }
+    case Instruction::BitCast:
+      return findGlobalValue(CE->getOperand(0));
+    default:
+      return 0;
+    }
+  }
+  return 0;
+}
+
 /// EmitLLVMUsedList - For targets that define a TAI::UsedDirective, mark each
-/// global in the specified llvm.used list as being used with this directive.
+/// global in the specified llvm.used list for which emitUsedDirectiveFor
+/// is true, as being used with this directive.
+
 void AsmPrinter::EmitLLVMUsedList(Constant *List) {
   const char *Directive = TAI->getUsedDirective();
 
@@ -441,9 +472,12 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) {
   if (InitList == 0) return;
   
   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
-    O << Directive;
-    EmitConstantValueOnly(InitList->getOperand(i));
-    O << '\n';
+    const GlobalValue *GV = findGlobalValue(InitList->getOperand(i));
+    if (TAI->emitUsedDirectiveFor(GV, Mang)) {
+      O << Directive;
+      EmitConstantValueOnly(InitList->getOperand(i));
+      O << '\n';
+    }
   }
 }
 
@@ -502,7 +536,7 @@ void AsmPrinter::PrintULEB128(unsigned Value) const {
     unsigned Byte = Value & 0x7f;
     Value >>= 7;
     if (Value) Byte |= 0x80;
-    O << "0x" << std::hex << Byte << std::dec;
+    O << "0x" <<  utohexstr(Byte);
     if (Value) O << ", ";
   } while (Value);
 }
@@ -518,7 +552,7 @@ void AsmPrinter::PrintSLEB128(int Value) const {
     Value >>= 7;
     IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
     if (IsMore) Byte |= 0x80;
-    O << "0x" << std::hex << Byte << std::dec;
+    O << "0x" << utohexstr(Byte);
     if (IsMore) O << ", ";
   } while (IsMore);
 }
@@ -530,7 +564,7 @@ void AsmPrinter::PrintSLEB128(int Value) const {
 /// PrintHex - Print a value as a hexidecimal value.
 ///
 void AsmPrinter::PrintHex(int Value) const { 
-  O << "0x" << std::hex << Value << std::dec;
+  O << "0x" << utohexstr(static_cast<unsigned>(Value));
 }
 
 /// EOL - Print a newline character to asm stream.  If a comment is present
@@ -629,7 +663,7 @@ static inline char toOctal(int X) {
 
 /// printStringChar - Print a char, escaped if necessary.
 ///
-static void printStringChar(std::ostream &O, unsigned char C) {
+static void printStringChar(raw_ostream &O, char C) {
   if (C == '"') {
     O << "\\\"";
   } else if (C == '\\') {
@@ -713,7 +747,7 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV,
 
   unsigned FillValue = TAI->getTextAlignFillValue();
   UseFillExpr &= IsInTextSection && FillValue;
-  if (UseFillExpr) O << ",0x" << std::hex << FillValue << std::dec;
+  if (UseFillExpr) O << ",0x" << utohexstr(FillValue);
   O << '\n';
 }
 
@@ -862,7 +896,7 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
 /// printAsCString - Print the specified array as a C compatible string, only if
 /// the predicate isString is true.
 ///
-static void printAsCString(std::ostream &O, const ConstantArray *CVA,
+static void printAsCString(raw_ostream &O, const ConstantArray *CVA,
                            unsigned LastElt) {
   assert(CVA->isString() && "Array is not string compatible!");
 
@@ -935,7 +969,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
     // precision...
     if (CFP->getType() == Type::DoubleTy) {
       double Val = CFP->getValueAPF().convertToDouble();  // for comment only
-      uint64_t i = CFP->getValueAPF().convertToAPInt().getZExtValue();
+      uint64_t i = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
       if (TAI->getData64bitsDirective())
         O << TAI->getData64bitsDirective() << i << '\t'
           << TAI->getCommentString() << " double value: " << Val << '\n';
@@ -958,16 +992,19 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
     } else if (CFP->getType() == Type::FloatTy) {
       float Val = CFP->getValueAPF().convertToFloat();  // for comment only
       O << TAI->getData32bitsDirective()
-        << CFP->getValueAPF().convertToAPInt().getZExtValue()
+        << CFP->getValueAPF().bitcastToAPInt().getZExtValue()
         << '\t' << TAI->getCommentString() << " float " << Val << '\n';
       return;
     } else if (CFP->getType() == Type::X86_FP80Ty) {
       // all long double variants are printed as hex
       // api needed to prevent premature destruction
-      APInt api = CFP->getValueAPF().convertToAPInt();
+      APInt api = CFP->getValueAPF().bitcastToAPInt();
       const uint64_t *p = api.getRawData();
+      // Convert to double so we can print the approximate val as a comment.
       APFloat DoubleVal = CFP->getValueAPF();
-      DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
+      bool ignored;
+      DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
+                        &ignored);
       if (TD->isBigEndian()) {
         O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
           << '\t' << TAI->getCommentString()
@@ -1008,7 +1045,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
     } else if (CFP->getType() == Type::PPC_FP128Ty) {
       // all long double variants are printed as hex
       // api needed to prevent premature destruction
-      APInt api = CFP->getValueAPF().convertToAPInt();
+      APInt api = CFP->getValueAPF().bitcastToAPInt();
       const uint64_t *p = api.getRawData();
       if (TD->isBigEndian()) {
         O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
@@ -1039,26 +1076,41 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
       }
       return;
     } else assert(0 && "Floating point constant type not handled");
-  } else if (CV->getType() == Type::Int64Ty) {
+  } else if (CV->getType()->isInteger() &&
+             cast<IntegerType>(CV->getType())->getBitWidth() >= 64) {
     if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
-      uint64_t Val = CI->getZExtValue();
-
-      if (TAI->getData64bitsDirective())
-        O << TAI->getData64bitsDirective() << Val << '\n';
-      else if (TD->isBigEndian()) {
-        O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
-          << '\t' << TAI->getCommentString()
-          << " Double-word most significant word " << Val << '\n';
-        O << TAI->getData32bitsDirective() << unsigned(Val)
-          << '\t' << TAI->getCommentString()
-          << " Double-word least significant word " << Val << '\n';
-      } else {
-        O << TAI->getData32bitsDirective() << unsigned(Val)
-          << '\t' << TAI->getCommentString()
-          << " Double-word least significant word " << Val << '\n';
-        O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
-          << '\t' << TAI->getCommentString()
-          << " Double-word most significant word " << Val << '\n';
+      unsigned BitWidth = CI->getBitWidth();
+      assert(isPowerOf2_32(BitWidth) &&
+             "Non-power-of-2-sized integers not handled!");
+
+      // We don't expect assemblers to support integer data directives
+      // for more than 64 bits, so we emit the data in at most 64-bit
+      // quantities at a time.
+      const uint64_t *RawData = CI->getValue().getRawData();
+      for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {
+        uint64_t Val;
+        if (TD->isBigEndian())
+          Val = RawData[e - i - 1];
+        else
+          Val = RawData[i];
+
+        if (TAI->getData64bitsDirective())
+          O << TAI->getData64bitsDirective() << Val << '\n';
+        else if (TD->isBigEndian()) {
+          O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+            << '\t' << TAI->getCommentString()
+            << " Double-word most significant word " << Val << '\n';
+          O << TAI->getData32bitsDirective() << unsigned(Val)
+            << '\t' << TAI->getCommentString()
+            << " Double-word least significant word " << Val << '\n';
+        } else {
+          O << TAI->getData32bitsDirective() << unsigned(Val)
+            << '\t' << TAI->getCommentString()
+            << " Double-word least significant word " << Val << '\n';
+          O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
+            << '\t' << TAI->getCommentString()
+            << " Double-word most significant word " << Val << '\n';
+        }
       }
       return;
     }
@@ -1130,11 +1182,11 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
   
   // Count the number of register definitions.
   unsigned NumDefs = 0;
-  for (; MI->getOperand(NumDefs).isRegister() && MI->getOperand(NumDefs).isDef();
+  for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
        ++NumDefs)
     assert(NumDefs != NumOperands-1 && "No asm string?");
   
-  assert(MI->getOperand(NumDefs).isExternalSymbol() && "No asm string?");
+  assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");
 
   // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
   const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
@@ -1194,21 +1246,17 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
         break;
       case '|':
         ++LastEmitted;  // consume '|' character.
-        if (CurVariant == -1) {
-          cerr << "Found '|' character outside of variant in inline asm "
-               << "string: '" << AsmStr << "'\n";
-          exit(1);
-        }
-        ++CurVariant;   // We're in the next variant.
+        if (CurVariant == -1)
+          O << '|';       // this is gcc's behavior for | outside a variant
+        else
+          ++CurVariant;   // We're in the next variant.
         break;
       case ')':         // $) -> same as GCC's } char.
         ++LastEmitted;  // consume ')' character.
-        if (CurVariant == -1) {
-          cerr << "Found '}' character outside of variant in inline asm "
-               << "string: '" << AsmStr << "'\n";
-          exit(1);
-        }
-        CurVariant = -1;
+        if (CurVariant == -1)
+          O << '}';     // this is gcc's behavior for } outside a variant
+        else 
+          CurVariant = -1;
         break;
       }
       if (Done) break;
@@ -1286,7 +1334,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
                                  false, false, false);
           else {
             AsmPrinter *AP = const_cast<AsmPrinter*>(this);
-            if ((OpFlags & 7) == 4 /*ADDR MODE*/) {
+            if ((OpFlags & 7) == 4) {
               Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant,
                                                 Modifier[0] ? Modifier : 0);
             } else {
@@ -1417,6 +1465,8 @@ void AsmPrinter::printDataDirective(const Type *type) {
       assert(TAI->getData64bitsDirective() &&
              "Target cannot handle 64-bit constant exprs!");
       O << TAI->getData64bitsDirective();
+    } else {
+      assert(0 && "Target cannot handle given data directive width!");
     }
     break;
   }
@@ -1470,40 +1520,26 @@ void AsmPrinter::printVisibility(const std::string& Name,
   }
 }
 
-GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(Collector *C) {
-  if (!C->usesMetadata())
+GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
+  if (!S->usesMetadata())
     return 0;
-<<<<<<< HEAD:lib/CodeGen/AsmPrinter.cpp
   
-  gcp_iterator GCPI = GCMetadataPrinters.find(C);
+  gcp_iterator GCPI = GCMetadataPrinters.find(S);
   if (GCPI != GCMetadataPrinters.end())
     return GCPI->second;
   
-  const char *Name = C->getName().c_str();
+  const char *Name = S->getName().c_str();
   
-=======
-
-  gcp_iterator GCPI = GCMetadataPrinters.find(C);
-  if (GCPI != GCMetadataPrinters.end())
-    return GCPI->second;
-
-  const char *Name = C->getName().c_str();
-
->>>>>>> Factor out asmprinters from collector interface.:lib/CodeGen/AsmPrinter.cpp
   for (GCMetadataPrinterRegistry::iterator
          I = GCMetadataPrinterRegistry::begin(),
          E = GCMetadataPrinterRegistry::end(); I != E; ++I)
     if (strcmp(Name, I->getName()) == 0) {
-      GCMetadataPrinter *GCP = I->instantiate();
-      GCP->Coll = C;
-      GCMetadataPrinters.insert(std::make_pair(C, GCP));
-      return GCP;
+      GCMetadataPrinter *GMP = I->instantiate();
+      GMP->S = S;
+      GCMetadataPrinters.insert(std::make_pair(S, GMP));
+      return GMP;
     }
-<<<<<<< HEAD:lib/CodeGen/AsmPrinter.cpp
   
-=======
-
->>>>>>> Factor out asmprinters from collector interface.:lib/CodeGen/AsmPrinter.cpp
-  cerr << "no GCMetadataPrinter registered for collector: " << Name << "\n";
+  cerr << "no GCMetadataPrinter registered for GC: " << Name << "\n";
   abort();
 }