Close list item tag, to conform with the style in this file. It's optional
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index b6f8313e5563f59894621cfffcb8f01cc289afb3..239760d2b085e69d2c20e1132c44649c5bfaf0aa 100644 (file)
@@ -26,7 +26,7 @@
 #include "llvm/Module.h"
 #include "llvm/ValueSymbolTable.h"
 #include "llvm/TypeSymbolTable.h"
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/CFG.h"
@@ -145,36 +145,17 @@ void TypePrinting::clear() {
   getTypeNamesMap(TypeNames).clear();
 }
 
-TypePrinting::TypePrinting(const Module *M) {
+bool TypePrinting::hasTypeName(const Type *Ty) const {
+  return getTypeNamesMap(TypeNames).count(Ty);
+}
+
+void TypePrinting::addTypeName(const Type *Ty, const std::string &N) {
+  getTypeNamesMap(TypeNames).insert(std::make_pair(Ty, N));
+}
+
+
+TypePrinting::TypePrinting() {
   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
-  // names into the TypeNames map.
-  const TypeSymbolTable &ST = M->getTypeSymbolTable();
-  for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end();
-       TI != E; ++TI) {
-    const Type *Ty = cast<Type>(TI->second);
-    
-    // As a heuristic, don't insert pointer to primitive types, because
-    // they are used too often to have a single useful name.
-    if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
-      const Type *PETy = PTy->getElementType();
-      if ((PETy->isPrimitiveType() || PETy->isInteger()) &&
-          !isa<OpaqueType>(PETy))
-        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);
-    getTypeNamesMap(TypeNames).insert(std::make_pair(Ty, NameOS.str()));
-  }
 }
 
 TypePrinting::~TypePrinting() {
@@ -185,15 +166,15 @@ TypePrinting::~TypePrinting() {
 /// use of type names or up references to shorten the type name where possible.
 void TypePrinting::CalcTypeName(const Type *Ty,
                                 SmallVectorImpl<const Type *> &TypeStack,
-                                raw_ostream &OS) {
+                                raw_ostream &OS, bool IgnoreTopLevelName) {
   // Check to see if the type is named.
-  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;
+  if (!IgnoreTopLevelName) {
+    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;
+    }
   }
   
   // Check to see if the Type is already on the stack...
@@ -292,13 +273,16 @@ void TypePrinting::CalcTypeName(const Type *Ty,
 /// printTypeInt - The internal guts of printing out a type that has a
 /// potentially named portion.
 ///
-void TypePrinting::print(const Type *Ty, raw_ostream &OS) {
+void TypePrinting::print(const Type *Ty, raw_ostream &OS,
+                         bool IgnoreTopLevelName) {
   // Check to see if the type is named.
   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;
+  if (!IgnoreTopLevelName) {
+    DenseMap<const Type*, std::string>::iterator I = TM.find(Ty);
+    if (I != TM.end()) {
+      OS << I->second;
+      return;
+    }
   }
   
   // Otherwise we have a type that has not been named but is a derived type.
@@ -308,33 +292,151 @@ void TypePrinting::print(const Type *Ty, raw_ostream &OS) {
   std::string TypeName;
   
   raw_string_ostream TypeOS(TypeName);
-  CalcTypeName(Ty, TypeStack, TypeOS);
+  CalcTypeName(Ty, TypeStack, TypeOS, IgnoreTopLevelName);
   OS << TypeOS.str();
 
   // Cache type name for later use.
-  TM.insert(std::make_pair(Ty, TypeOS.str()));
+  if (!IgnoreTopLevelName)
+    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, 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);
+namespace {
+  class TypeFinder {
+    // To avoid walking constant expressions multiple times and other IR
+    // objects, we keep several helper maps.
+    DenseSet<const Value*> VisitedConstants;
+    DenseSet<const Type*> VisitedTypes;
+    
+    TypePrinting &TP;
+    std::vector<const Type*> &NumberedTypes;
+  public:
+    TypeFinder(TypePrinting &tp, std::vector<const Type*> &numberedTypes)
+      : TP(tp), NumberedTypes(numberedTypes) {}
+    
+    void Run(const Module &M) {
+      // Get types from the type symbol table.  This gets opaque types referened
+      // only through derived named types.
+      const TypeSymbolTable &ST = M.getTypeSymbolTable();
+      for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end();
+           TI != E; ++TI)
+        IncorporateType(TI->second);
+      
+      // Get types from global variables.
+      for (Module::const_global_iterator I = M.global_begin(),
+           E = M.global_end(); I != E; ++I) {
+        IncorporateType(I->getType());
+        if (I->hasInitializer())
+          IncorporateValue(I->getInitializer());
+      }
+      
+      // Get types from aliases.
+      for (Module::const_alias_iterator I = M.alias_begin(),
+           E = M.alias_end(); I != E; ++I) {
+        IncorporateType(I->getType());
+        IncorporateValue(I->getAliasee());
+      }
+      
+      // Get types from functions.
+      for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) {
+        IncorporateType(FI->getType());
+        
+        for (Function::const_iterator BB = FI->begin(), E = FI->end();
+             BB != E;++BB)
+          for (BasicBlock::const_iterator II = BB->begin(),
+               E = BB->end(); II != E; ++II) {
+            const Instruction &I = *II;
+            // Incorporate the type of the instruction and all its operands.
+            IncorporateType(I.getType());
+            for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
+                 OI != OE; ++OI)
+              IncorporateValue(*OI);
+          }
+      }
+    }
+    
+  private:
+    void IncorporateType(const Type *Ty) {
+      // Check to see if we're already visited this type.
+      if (!VisitedTypes.insert(Ty).second)
+        return;
+      
+      // If this is a structure or opaque type, add a name for the type.
+      if ((isa<StructType>(Ty) || isa<OpaqueType>(Ty))
+          && !TP.hasTypeName(Ty)) {
+        TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size())));
+        NumberedTypes.push_back(Ty);
+      }
+      
+      // Recursively walk all contained types.
+      for (Type::subtype_iterator I = Ty->subtype_begin(),
+           E = Ty->subtype_end(); I != E; ++I)
+        IncorporateType(*I);      
+    }
+    
+    /// IncorporateValue - This method is used to walk operand lists finding
+    /// types hiding in constant expressions and other operands that won't be
+    /// walked in other ways.  GlobalValues, basic blocks, instructions, and
+    /// inst operands are all explicitly enumerated.
+    void IncorporateValue(const Value *V) {
+      if (V == 0 || !isa<Constant>(V) || isa<GlobalValue>(V)) return;
+      
+      // Already visited?
+      if (!VisitedConstants.insert(V).second)
+        return;
+      
+      // Check this type.
+      IncorporateType(V->getType());
+      
+      // Look in operands for types.
+      const Constant *C = cast<Constant>(V);
+      for (Constant::const_op_iterator I = C->op_begin(),
+           E = C->op_end(); I != E;++I)
+        IncorporateValue(*I);
+    }
+  };
+} // end anonymous namespace
 
-  // Print the type without the name.
-  SmallVector<const Type *, 16> TypeStack;
-  CalcTypeName(Ty, TypeStack, OS);
 
-  // Restore the name.
-  std::swap(OldName, I->second);
+/// AddModuleTypesToPrinter - Add all of the symbolic type names for types in
+/// the specified module to the TypePrinter and all numbered types to it and the
+/// NumberedTypes table.
+static void AddModuleTypesToPrinter(TypePrinting &TP, 
+                                    std::vector<const Type*> &NumberedTypes,
+                                    const Module *M) {
+  if (M == 0) return;
+  
+  // If the module has a symbol table, take all global types and stuff their
+  // names into the TypeNames map.
+  const TypeSymbolTable &ST = M->getTypeSymbolTable();
+  for (TypeSymbolTable::const_iterator TI = ST.begin(), E = ST.end();
+       TI != E; ++TI) {
+    const Type *Ty = cast<Type>(TI->second);
+    
+    // As a heuristic, don't insert pointer to primitive types, because
+    // they are used too often to have a single useful name.
+    if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
+      const Type *PETy = PTy->getElementType();
+      if ((PETy->isPrimitiveType() || PETy->isInteger()) &&
+          !isa<OpaqueType>(PETy))
+        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);
+    TP.addTypeName(Ty, NameOS.str());
+  }
+  
+  // Walk the entire module to find references to unnamed structure and opaque
+  // types.  This is required for correctness by opaque types (because multiple
+  // uses of an unnamed opaque type needs to be referred to by the same ID) and
+  // it shrinks complex recursive structure types substantially in some cases.
+  TypeFinder(TP, NumberedTypes).Run(*M);
 }
 
 
@@ -342,8 +444,11 @@ void TypePrinting::printAtLeastOneLevel(const Type *Ty, raw_ostream &OS) {
 /// type, iff there is an entry in the modules symbol table for the specified
 /// type or one of it's component types.
 ///
-void llvm::WriteTypeSymbolic(raw_ostream &OS, const Type *Ty, const Module *M){
-  TypePrinting(M).print(Ty, OS);
+void llvm::WriteTypeSymbolic(raw_ostream &OS, const Type *Ty, const Module *M) {
+  TypePrinting Printer;
+  std::vector<const Type*> NumberedTypes;
+  AddModuleTypesToPrinter(Printer, NumberedTypes, M);
+  Printer.print(Ty, OS);
 }
 
 //===----------------------------------------------------------------------===//
@@ -918,7 +1023,9 @@ void llvm::WriteAsOperand(raw_ostream &Out, const Value *V, bool PrintType,
                           const Module *Context) {
   if (Context == 0) Context = getModuleFromVal(V);
 
-  TypePrinting TypePrinter(Context);
+  TypePrinting TypePrinter;
+  std::vector<const Type*> NumberedTypes;
+  AddModuleTypesToPrinter(TypePrinter, NumberedTypes, Context);
   if (PrintType) {
     TypePrinter.print(V->getType(), Out);
     Out << ' ';
@@ -936,14 +1043,15 @@ class AssemblyWriter {
   const Module *TheModule;
   TypePrinting TypePrinter;
   AssemblyAnnotationWriter *AnnotationWriter;
+  std::vector<const Type*> NumberedTypes;
 public:
   inline AssemblyWriter(raw_ostream &o, SlotTracker &Mac, const Module *M,
                         AssemblyAnnotationWriter *AAW)
-    : Out(o), Machine(Mac), TheModule(M), TypePrinter(M),
-      AnnotationWriter(AAW) {
+    : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) {
+    AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M);
   }
 
-  void write(const Module *M) { printModule(M);       }
+  void write(const Module *M) { printModule(M); }
   
   void write(const GlobalValue *G) {
     if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(G))
@@ -978,7 +1086,7 @@ private:
   // which slot it occupies.
   void printInfoComment(const Value &V);
 };
-}  // end of llvm namespace
+}  // end of anonymous namespace
 
 
 void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
@@ -1055,7 +1163,7 @@ void AssemblyWriter::printModule(const Module *M) {
     Out << " ]\n";
   }
 
-  // Loop over the symbol table, emitting all named constants.
+  // Loop over the symbol table, emitting all id'd types.
   printTypeSymbolTable(M->getTypeSymbolTable());
 
   for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
@@ -1177,7 +1285,17 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
 }
 
 void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
-  // Print the types.
+  // Emit all numbered types.
+  for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) {
+    Out << "\ttype ";
+    
+    // Make sure we print out at least one level of the type structure, so
+    // that we do not get %2 = type %2
+    TypePrinter.printAtLeastOneLevel(NumberedTypes[i], Out);
+    Out << "\t\t; type %" << i << '\n';
+  }
+  
+  // Print the named types.
   for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
        TI != TE; ++TI) {
     Out << '\t';
@@ -1649,7 +1767,7 @@ void Type::print(raw_ostream &OS) const {
     OS << "<null Type>";
     return;
   }
-  TypePrinting(0).print(this, OS);
+  TypePrinting().print(this, OS);
 }
 
 void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const {
@@ -1673,7 +1791,7 @@ 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)) {
-    TypePrinting TypePrinter(0);
+    TypePrinting TypePrinter;
     TypePrinter.print(C->getType(), OS);
     OS << ' ';
     WriteConstantInt(OS, C, TypePrinter, 0);
@@ -1706,8 +1824,5 @@ void Type::dump(const Module *Context) const {
 // 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(); }
-
-