switch to densemap for pointer->word map.
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index d67b2a20f478b7491ee93f1c4c321c9d3be06fd1..b6f8313e5563f59894621cfffcb8f01cc289afb3 100644 (file)
@@ -137,24 +137,16 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) {
 // TypePrinting Class: Type printing machinery
 //===----------------------------------------------------------------------===//
 
-namespace {
-  /// TypePrinting - Type printing machinery.
-  class TypePrinting {
-    std::map<const Type *, std::string> TypeNames;
-    raw_ostream &OS;
-  public:
-    TypePrinting(const Module *M, raw_ostream &os);
-    
-    void print(const Type *Ty);
-    void printAtLeastOneLevel(const Type *Ty);
-    
-  private:
-    void calcTypeName(const Type *Ty, SmallVectorImpl<const Type *> &TypeStack,
-                      std::string &Result);
-  };
-} // end anonymous namespace.
+static DenseMap<const Type *, std::string> &getTypeNamesMap(void *M) {
+  return *static_cast<DenseMap<const Type *, std::string>*>(M);
+}
 
-TypePrinting::TypePrinting(const Module *M, raw_ostream &os) : OS(os) {
+void TypePrinting::clear() {
+  getTypeNamesMap(TypeNames).clear();
+}
+
+TypePrinting::TypePrinting(const Module *M) {
+  TypeNames = new DenseMap<const Type *, std::string>();
   if (M == 0) return;
   
   // If the module has a symbol table, take all global types and stuff their
@@ -173,31 +165,34 @@ TypePrinting::TypePrinting(const Module *M, raw_ostream &os) : OS(os) {
         continue;
     }
     
+    // Likewise don't insert primitives either.
+    if (Ty->isInteger() || Ty->isPrimitiveType())
+      continue;
+    
     // Get the name as a string and insert it into TypeNames.
     std::string NameStr;
     raw_string_ostream NameOS(NameStr);
     PrintLLVMName(NameOS, TI->first.c_str(), TI->first.length(), LocalPrefix);
-    TypeNames.insert(std::make_pair(Ty, NameOS.str()));
+    getTypeNamesMap(TypeNames).insert(std::make_pair(Ty, NameOS.str()));
   }
 }
 
-void TypePrinting::calcTypeName(const Type *Ty,
+TypePrinting::~TypePrinting() {
+  delete &getTypeNamesMap(TypeNames);
+}
+
+/// CalcTypeName - Write the specified type to the specified raw_ostream, making
+/// use of type names or up references to shorten the type name where possible.
+void TypePrinting::CalcTypeName(const Type *Ty,
                                 SmallVectorImpl<const Type *> &TypeStack,
-                                std::string &Result) {
-  if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))) {
-    Result += Ty->getDescription();  // Base case
-    return;
-  }
-  
+                                raw_ostream &OS) {
   // Check to see if the type is named.
-  std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty);
-  if (I != TypeNames.end()) {
-    Result += I->second;
-    return;
-  }
-  
-  if (isa<OpaqueType>(Ty)) {
-    Result += "opaque";
+  DenseMap<const Type*, std::string> &TM = getTypeNamesMap(TypeNames);
+  DenseMap<const Type *, std::string>::iterator I = TM.find(Ty);
+  if (I != TM.end() &&
+      // If the name wasn't temporarily removed use it.
+      !I->second.empty()) {
+    OS << I->second;
     return;
   }
   
@@ -209,94 +204,99 @@ void TypePrinting::calcTypeName(const Type *Ty,
   // that we have looped back to a type that we have previously visited.
   // Generate the appropriate upreference to handle this.
   if (Slot < CurSize) {
-    Result += "\\" + utostr(CurSize-Slot);     // Here's the upreference
+    OS << '\\' << unsigned(CurSize-Slot);     // Here's the upreference
     return;
   }
   
   TypeStack.push_back(Ty);    // Recursive case: Add us to the stack..
   
   switch (Ty->getTypeID()) {
+  case Type::VoidTyID:      OS << "void"; break;
+  case Type::FloatTyID:     OS << "float"; break;
+  case Type::DoubleTyID:    OS << "double"; break;
+  case Type::X86_FP80TyID:  OS << "x86_fp80"; break;
+  case Type::FP128TyID:     OS << "fp128"; break;
+  case Type::PPC_FP128TyID: OS << "ppc_fp128"; break;
+  case Type::LabelTyID:     OS << "label"; break;
+  case Type::IntegerTyID:
+    OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
+    break;
+      
   case Type::FunctionTyID: {
     const FunctionType *FTy = cast<FunctionType>(Ty);
-    calcTypeName(FTy->getReturnType(), TypeStack, Result);
-    Result += " (";
+    CalcTypeName(FTy->getReturnType(), TypeStack, OS);
+    OS << " (";
     for (FunctionType::param_iterator I = FTy->param_begin(),
          E = FTy->param_end(); I != E; ++I) {
       if (I != FTy->param_begin())
-        Result += ", ";
-      calcTypeName(*I, TypeStack, Result);
+        OS << ", ";
+      CalcTypeName(*I, TypeStack, OS);
     }
     if (FTy->isVarArg()) {
-      if (FTy->getNumParams()) Result += ", ";
-      Result += "...";
+      if (FTy->getNumParams()) OS << ", ";
+      OS << "...";
     }
-    Result += ")";
+    OS << ')';
     break;
   }
   case Type::StructTyID: {
     const StructType *STy = cast<StructType>(Ty);
     if (STy->isPacked())
-      Result += '<';
-    Result += "{ ";
+      OS << '<';
+    OS << "{ ";
     for (StructType::element_iterator I = STy->element_begin(),
          E = STy->element_end(); I != E; ++I) {
-      calcTypeName(*I, TypeStack, Result);
+      CalcTypeName(*I, TypeStack, OS);
       if (next(I) != STy->element_end())
-        Result += ',';
-      Result += ' ';
+        OS << ',';
+      OS << ' ';
     }
-    Result += '}';
+    OS << '}';
     if (STy->isPacked())
-      Result += '>';
+      OS << '>';
     break;
   }
   case Type::PointerTyID: {
     const PointerType *PTy = cast<PointerType>(Ty);
-    calcTypeName(PTy->getElementType(), TypeStack, Result);
+    CalcTypeName(PTy->getElementType(), TypeStack, OS);
     if (unsigned AddressSpace = PTy->getAddressSpace())
-      Result += " addrspace(" + utostr(AddressSpace) + ")";
-    Result += "*";
+      OS << " addrspace(" << AddressSpace << ')';
+    OS << '*';
     break;
   }
   case Type::ArrayTyID: {
     const ArrayType *ATy = cast<ArrayType>(Ty);
-    Result += "[" + utostr(ATy->getNumElements()) + " x ";
-    calcTypeName(ATy->getElementType(), TypeStack, Result);
-    Result += "]";
+    OS << '[' << ATy->getNumElements() << " x ";
+    CalcTypeName(ATy->getElementType(), TypeStack, OS);
+    OS << ']';
     break;
   }
   case Type::VectorTyID: {
     const VectorType *PTy = cast<VectorType>(Ty);
-    Result += "<" + utostr(PTy->getNumElements()) + " x ";
-    calcTypeName(PTy->getElementType(), TypeStack, Result);
-    Result += ">";
+    OS << "<" << PTy->getNumElements() << " x ";
+    CalcTypeName(PTy->getElementType(), TypeStack, OS);
+    OS << '>';
     break;
   }
   case Type::OpaqueTyID:
-    Result += "opaque";
+    OS << "opaque";
     break;
   default:
-    Result += "<unrecognized-type>";
+    OS << "<unrecognized-type>";
     break;
   }
   
-  TypeStack.pop_back();       // Remove self from stack...
+  TypeStack.pop_back();       // Remove self from stack.
 }
 
 /// printTypeInt - The internal guts of printing out a type that has a
 /// potentially named portion.
 ///
-void TypePrinting::print(const Type *Ty) {
-  // Primitive types always print out their description, regardless of whether
-  // they have been named or not.
-  if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))) {
-    OS << Ty->getDescription();
-    return;
-  }
-  
+void TypePrinting::print(const Type *Ty, raw_ostream &OS) {
   // Check to see if the type is named.
-  std::map<const Type*, std::string>::iterator I = TypeNames.find(Ty);
-  if (I != TypeNames.end()) {
+  DenseMap<const Type*, std::string> &TM = getTypeNamesMap(TypeNames);
+  DenseMap<const Type*, std::string>::iterator I = TM.find(Ty);
+  if (I != TM.end()) {
     OS << I->second;
     return;
   }
@@ -306,108 +306,46 @@ void TypePrinting::print(const Type *Ty) {
   // names.
   SmallVector<const Type *, 16> TypeStack;
   std::string TypeName;
-  calcTypeName(Ty, TypeStack, TypeName);
-  TypeNames.insert(std::make_pair(Ty, TypeName));//Cache type name for later use
-  OS << TypeName;
+  
+  raw_string_ostream TypeOS(TypeName);
+  CalcTypeName(Ty, TypeStack, TypeOS);
+  OS << TypeOS.str();
+
+  // Cache type name for later use.
+  TM.insert(std::make_pair(Ty, TypeOS.str()));
 }
 
 /// printAtLeastOneLevel - Print out one level of the possibly complex type
 /// without considering any symbolic types that we may have equal to it.
-void TypePrinting::printAtLeastOneLevel(const Type *Ty) {
-  // FIXME: Just call calcTypeName!
-  if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
-    print(FTy->getReturnType());
-    OS << " (";
-    for (FunctionType::param_iterator I = FTy->param_begin(),
-         E = FTy->param_end(); I != E; ++I) {
-      if (I != FTy->param_begin())
-        OS << ", ";
-      print(*I);
-    }
-    if (FTy->isVarArg()) {
-      if (FTy->getNumParams()) OS << ", ";
-      OS << "...";
-    }
-    OS << ')';
-    return;
-  }
-  
-  if (const StructType *STy = dyn_cast<StructType>(Ty)) {
-    if (STy->isPacked())
-      OS << '<';
-    OS << "{ ";
-    for (StructType::element_iterator I = STy->element_begin(),
-         E = STy->element_end(); I != E; ++I) {
-      if (I != STy->element_begin())
-        OS << ", ";
-      print(*I);
-    }
-    OS << " }";
-    if (STy->isPacked())
-      OS << '>';
-    return;
-  }
-  
-  if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
-    print(PTy->getElementType());
-    if (unsigned AddressSpace = PTy->getAddressSpace())
-      OS << " addrspace(" << AddressSpace << ")";
-    OS << '*';
-    return;
-  } 
-  
-  if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
-    OS << '[' << ATy->getNumElements() << " x ";
-    print(ATy->getElementType());
-    OS << ']';
-    return;
-  }
-  
-  if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) {
-    OS << '<' << PTy->getNumElements() << " x ";
-    print(PTy->getElementType());
-    OS << '>';
-    return;
-  }
-  
-  if (isa<OpaqueType>(Ty)) {
-    OS << "opaque";
-    return;
-  }
-  
-  if (!Ty->isPrimitiveType() && !isa<IntegerType>(Ty))
-    OS << "<unknown derived type>";
-  print(Ty);
-}
-
+void TypePrinting::printAtLeastOneLevel(const Type *Ty, raw_ostream &OS) {
+  // If the type does not have a name, then it is already guaranteed to print at
+  // least one level.
+  DenseMap<const Type*, std::string> &TM = getTypeNamesMap(TypeNames);
+  DenseMap<const Type*, std::string>::iterator I = TM.find(Ty);
+  if (I == TM.end())
+    return print(Ty, OS);
+  
+  // Otherwise, temporarily remove the name and print it.
+  std::string OldName;
+  std::swap(OldName, I->second);
+
+  // Print the type without the name.
+  SmallVector<const Type *, 16> TypeStack;
+  CalcTypeName(Ty, TypeStack, OS);
 
+  // Restore the name.
+  std::swap(OldName, I->second);
+}
 
 
 /// WriteTypeSymbolic - This attempts to write the specified type as a symbolic
 /// type, iff there is an entry in the modules symbol table for the specified
-/// type or one of it's component types. This is slower than a simple x << Type
+/// type or one of it's component types.
 ///
-void llvm::WriteTypeSymbolic(raw_ostream &Out, const Type *Ty, const Module *M){
-  // FIXME: Remove this space.
-  Out << ' ';
-  
-  // If they want us to print out a type, but there is no context, we can't
-  // print it symbolically.
-  if (!M) {
-    Out << Ty->getDescription();
-  } else {
-    TypePrinting(M, Out).print(Ty);
-  }
+void llvm::WriteTypeSymbolic(raw_ostream &OS, const Type *Ty, const Module *M){
+  TypePrinting(M).print(Ty, OS);
 }
 
-// std::ostream adaptor.
-void llvm::WriteTypeSymbolic(std::ostream &Out, const Type *Ty,
-                             const Module *M) {
-  raw_os_ostream RO(Out);
-  WriteTypeSymbolic(RO, Ty, M);
-}
-
-
 //===----------------------------------------------------------------------===//
 // SlotTracker Class: Enumerate slot numbers for unnamed values
 //===----------------------------------------------------------------------===//
@@ -801,13 +739,13 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
     } else {                // Cannot output in string format...
       Out << '[';
       if (CA->getNumOperands()) {
-        TypePrinter.print(ETy);
+        TypePrinter.print(ETy, Out);
         Out << ' ';
         WriteAsOperandInternal(Out, CA->getOperand(0),
                                TypePrinter, Machine);
         for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
           Out << ", ";
-          TypePrinter.print(ETy);
+          TypePrinter.print(ETy, Out);
           Out << ' ';
           WriteAsOperandInternal(Out, CA->getOperand(i), TypePrinter, Machine);
         }
@@ -824,14 +762,14 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
     unsigned N = CS->getNumOperands();
     if (N) {
       Out << ' ';
-      TypePrinter.print(CS->getOperand(0)->getType());
+      TypePrinter.print(CS->getOperand(0)->getType(), Out);
       Out << ' ';
 
       WriteAsOperandInternal(Out, CS->getOperand(0), TypePrinter, Machine);
 
       for (unsigned i = 1; i < N; i++) {
         Out << ", ";
-        TypePrinter.print(CS->getOperand(i)->getType());
+        TypePrinter.print(CS->getOperand(i)->getType(), Out);
         Out << ' ';
 
         WriteAsOperandInternal(Out, CS->getOperand(i), TypePrinter, Machine);
@@ -850,12 +788,12 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
     assert(CP->getNumOperands() > 0 &&
            "Number of operands for a PackedConst must be > 0");
     Out << '<';
-    TypePrinter.print(ETy);
+    TypePrinter.print(ETy, Out);
     Out << ' ';
     WriteAsOperandInternal(Out, CP->getOperand(0), TypePrinter, Machine);
     for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
       Out << ", ";
-      TypePrinter.print(ETy);
+      TypePrinter.print(ETy, Out);
       Out << ' ';
       WriteAsOperandInternal(Out, CP->getOperand(i), TypePrinter, Machine);
     }
@@ -880,7 +818,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
     Out << " (";
 
     for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
-      TypePrinter.print((*OI)->getType());
+      TypePrinter.print((*OI)->getType(), Out);
       Out << ' ';
       WriteAsOperandInternal(Out, *OI, TypePrinter, Machine);
       if (OI+1 != CE->op_end())
@@ -895,7 +833,7 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
 
     if (CE->isCast()) {
       Out << " to ";
-      TypePrinter.print(CE->getType());
+      TypePrinter.print(CE->getType(), Out);
     }
 
     Out << ')';
@@ -980,9 +918,9 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, bool PrintType,
                           const Module *Context) {
   if (Context == 0) Context = getModuleFromVal(V);
 
-  TypePrinting TypePrinter(Context, Out);
+  TypePrinting TypePrinter(Context);
   if (PrintType) {
-    TypePrinter.print(V->getType());
+    TypePrinter.print(V->getType(), Out);
     Out << ' ';
   }
 
@@ -1001,7 +939,7 @@ class AssemblyWriter {
 public:
   inline AssemblyWriter(raw_ostream &o, SlotTracker &Mac, const Module *M,
                         AssemblyAnnotationWriter *AAW)
-    : Out(o), Machine(Mac), TheModule(M), TypePrinter(M, Out),
+    : Out(o), Machine(Mac), TheModule(M), TypePrinter(M),
       AnnotationWriter(AAW) {
   }
 
@@ -1020,7 +958,6 @@ public:
   
   void write(const BasicBlock *BB)    { printBasicBlock(BB);  }
   void write(const Instruction *I)    { printInstruction(*I); }
-//  void write(const Type *Ty)          { printType(Ty);        }
 
   void writeOperand(const Value *Op, bool PrintType);
   void writeParamOperand(const Value *Operand, Attributes Attrs);
@@ -1037,13 +974,6 @@ private:
   void printBasicBlock(const BasicBlock *BB);
   void printInstruction(const Instruction &I);
 
-  // printType - Go to extreme measures to attempt to print out a short,
-  // symbolic version of a type name.
-  //
-  void printType(const Type *Ty) {
-    TypePrinter.print(Ty);
-  }
-
   // printInfoComment - Print a little comment after the instruction indicating
   // which slot it occupies.
   void printInfoComment(const Value &V);
@@ -1056,7 +986,7 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
     Out << "<null operand!>";
   } else {
     if (PrintType) {
-      printType(Operand->getType());
+      TypePrinter.print(Operand->getType(), Out);
       Out << ' ';
     }
     WriteAsOperandInternal(Out, Operand, TypePrinter, &Machine);
@@ -1069,7 +999,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand,
     Out << "<null operand!>";
   } else {
     // Print the type
-    printType(Operand->getType());
+    TypePrinter.print(Operand->getType(), Out);
     // Print parameter attributes list
     if (Attrs != Attribute::None)
       Out << ' ' << Attribute::getAsString(Attrs);
@@ -1188,7 +1118,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
   if (unsigned AddressSpace = GV->getType()->getAddressSpace())
     Out << "addrspace(" << AddressSpace << ") ";
   Out << (GV->isConstant() ? "constant " : "global ");
-  printType(GV->getType()->getElementType());
+  TypePrinter.print(GV->getType()->getElementType(), Out);
 
   if (GV->hasInitializer()) {
     Out << ' ';
@@ -1221,17 +1151,17 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
   const Constant *Aliasee = GA->getAliasee();
     
   if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
-    printType(GV->getType());
+    TypePrinter.print(GV->getType(), Out);
     Out << ' ';
     PrintLLVMName(Out, GV);
   } else if (const Function *F = dyn_cast<Function>(Aliasee)) {
-    printType(F->getFunctionType());
+    TypePrinter.print(F->getFunctionType(), Out);
     Out << "* ";
 
     WriteAsOperandInternal(Out, F, TypePrinter, &Machine);
   } else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(Aliasee)) {
-    printType(GA->getType());
-    Out << " ";
+    TypePrinter.print(GA->getType(), Out);
+    Out << ' ';
     PrintLLVMName(Out, GA);
   } else {
     const ConstantExpr *CE = 0;
@@ -1256,7 +1186,7 @@ void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
 
     // Make sure we print out at least one level of the type structure, so
     // that we do not get %FILE = type %FILE
-    TypePrinter.printAtLeastOneLevel(TI->second); 
+    TypePrinter.printAtLeastOneLevel(TI->second, Out);
     Out << '\n';
   }
 }
@@ -1292,7 +1222,7 @@ void AssemblyWriter::printFunction(const Function *F) {
   Attributes RetAttrs = Attrs.getRetAttributes();
   if (RetAttrs != Attribute::None)
     Out <<  Attribute::getAsString(Attrs.getRetAttributes()) << ' ';
-  printType(F->getReturnType());
+  TypePrinter.print(F->getReturnType(), Out);
   Out << ' ';
   WriteAsOperandInternal(Out, F, TypePrinter, &Machine);
   Out << '(';
@@ -1317,7 +1247,7 @@ void AssemblyWriter::printFunction(const Function *F) {
       if (i) Out << ", ";
       
       // Output type...
-      printType(FT->getParamType(i));
+      TypePrinter.print(FT->getParamType(i), Out);
       
       Attributes ArgAttrs = Attrs.getParamAttributes(i+1);
       if (ArgAttrs != Attribute::None)
@@ -1361,7 +1291,7 @@ void AssemblyWriter::printFunction(const Function *F) {
 void AssemblyWriter::printArgument(const Argument *Arg, 
                                    Attributes Attrs) {
   // Output type...
-  printType(Arg->getType());
+  TypePrinter.print(Arg->getType(), Out);
 
   // Output parameter attributes list
   if (Attrs != Attribute::None)
@@ -1427,7 +1357,7 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
 void AssemblyWriter::printInfoComment(const Value &V) {
   if (V.getType() != Type::VoidTy) {
     Out << "\t\t; <";
-    printType(V.getType());
+    TypePrinter.print(V.getType(), Out);
     Out << '>';
 
     if (!V.hasName() && !isa<Instruction>(V)) {
@@ -1510,7 +1440,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     Out << "\n\t]";
   } else if (isa<PHINode>(I)) {
     Out << ' ';
-    printType(I.getType());
+    TypePrinter.print(I.getType(), Out);
     Out << ' ';
 
     for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
@@ -1559,7 +1489,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     if (!FTy->isVarArg() &&
         (!isa<PointerType>(RetTy) ||
          !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
-      printType(RetTy);
+      TypePrinter.print(RetTy, Out);
       Out << ' ';
       writeOperand(Operand, false);
     } else {
@@ -1601,7 +1531,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     if (!FTy->isVarArg() &&
         (!isa<PointerType>(RetTy) ||
          !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
-      printType(RetTy);
+      TypePrinter.print(RetTy, Out);
       Out << ' ';
       writeOperand(Operand, false);
     } else {
@@ -1625,7 +1555,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
 
   } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) {
     Out << ' ';
-    printType(AI->getType()->getElementType());
+    TypePrinter.print(AI->getType()->getElementType(), Out);
     if (AI->isArrayAllocation()) {
       Out << ", ";
       writeOperand(AI->getArraySize(), true);
@@ -1639,15 +1569,15 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
       writeOperand(Operand, true);   // Work with broken code
     }
     Out << " to ";
-    printType(I.getType());
+    TypePrinter.print(I.getType(), Out);
   } else if (isa<VAArgInst>(I)) {
     if (Operand) {
       Out << ' ';
       writeOperand(Operand, true);   // Work with broken code
     }
     Out << ", ";
-    printType(I.getType());
-  } else if (Operand) {   // Print the normal way...
+    TypePrinter.print(I.getType(), Out);
+  } else if (Operand) {   // Print the normal way.
 
     // PrintAllTypes - Instructions who have operands of all the same type
     // omit the type from all but the first operand.  If the instruction has
@@ -1673,7 +1603,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
 
     if (!PrintAllTypes) {
       Out << ' ';
-      printType(TheType);
+      TypePrinter.print(TheType, Out);
     }
 
     Out << ' ';
@@ -1714,11 +1644,12 @@ void Type::print(std::ostream &o) const {
   print(OS);
 }
 
-void Type::print(raw_ostream &o) const {
-  if (this == 0)
-    o << "<null Type>";
-  else
-    o << getDescription();
+void Type::print(raw_ostream &OS) const {
+  if (this == 0) {
+    OS << "<null Type>";
+    return;
+  }
+  TypePrinting(0).print(this, OS);
 }
 
 void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const {
@@ -1742,8 +1673,9 @@ void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const {
     AssemblyWriter W(OS, SlotTable, GV->getParent(), 0);
     W.write(GV);
   } else if (const Constant *C = dyn_cast<Constant>(this)) {
-    OS << C->getType()->getDescription() << ' ';
-    TypePrinting TypePrinter(0, OS);
+    TypePrinting TypePrinter(0);
+    TypePrinter.print(C->getType(), OS);
+    OS << ' ';
     WriteConstantInt(OS, C, TypePrinter, 0);
   } else if (const Argument *A = dyn_cast<Argument>(this)) {
     WriteAsOperand(OS, this, true,
@@ -1763,9 +1695,6 @@ void Value::print(std::ostream &O, AssemblyAnnotationWriter *AAW) const {
 // Value::dump - allow easy printing of Values from the debugger.
 void Value::dump() const { print(errs()); errs() << '\n'; errs().flush(); }
 
-// Type::dump - allow easy printing of Types from the debugger.
-void Type::dump() const { print(errs()); errs() << '\n'; errs().flush(); }
-
 // Type::dump - allow easy printing of Types from the debugger.
 // This one uses type names from the given context module
 void Type::dump(const Module *Context) const {
@@ -1774,6 +1703,10 @@ void Type::dump(const Module *Context) const {
   errs().flush();
 }
 
+// Type::dump - allow easy printing of Types from the debugger.
+void Type::dump() const { dump(0); }
+
+
 // Module::dump() - Allow printing of Modules from the debugger.
 void Module::dump() const { print(errs(), 0); errs().flush(); }