Adding a collector name attribute to Function in the IR. These
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index b9b2e8fe9e70d5325281efe522fbe2747205c617..008c1daee192b91d53d246ec4eb81d146289872b 100644 (file)
@@ -1,5 +1,12 @@
 //===-- AsmWriter.cpp - Printing LLVM as an assembly file -----------------===//
 //
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
 // This library implements the functionality defined in llvm/Assembly/Writer.h
 //
 // Note that these routines must be extremely tolerant of various errors in the
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Assembly/CachedWriter.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/SlotCalculator.h"
+#include "llvm/Assembly/AsmAnnotationWriter.h"
+#include "llvm/CallingConv.h"
+#include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/ParameterAttributes.h"
+#include "llvm/InlineAsm.h"
 #include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
 #include "llvm/Module.h"
-#include "llvm/Constants.h"
-#include "llvm/iMemory.h"
-#include "llvm/iTerminators.h"
-#include "llvm/iPHINode.h"
-#include "llvm/iOther.h"
-#include "llvm/SymbolTable.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/TypeSymbolTable.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/CFG.h"
-#include "Support/StringExtras.h"
-#include "Support/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Streams.h"
 #include <algorithm>
+#include <cctype>
+using namespace llvm;
+
+namespace llvm {
+
+// Make virtual table appear in this compilation unit.
+AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {}
+
+/// This class provides computation of slot numbers for LLVM Assembly writing.
+/// @brief LLVM Assembly Writing Slot Computation.
+class SlotMachine {
+
+/// @name Types
+/// @{
+public:
+
+  /// @brief A mapping of Values to slot numbers
+  typedef std::map<const Value*,unsigned> ValueMap;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
+  /// @brief Construct from a module
+  SlotMachine(const Module *M);
+
+  /// @brief Construct from a function, starting out in incorp state.
+  SlotMachine(const Function *F);
+
+/// @}
+/// @name Accessors
+/// @{
+public:
+  /// Return the slot number of the specified value in it's type
+  /// plane.  If something is not in the SlotMachine, return -1.
+  int getLocalSlot(const Value *V);
+  int getGlobalSlot(const GlobalValue *V);
+
+/// @}
+/// @name Mutators
+/// @{
+public:
+  /// If you'd like to deal with a function instead of just a module, use
+  /// this method to get its data into the SlotMachine.
+  void incorporateFunction(const Function *F) {
+    TheFunction = F;
+    FunctionProcessed = false;
+  }
+
+  /// After calling incorporateFunction, use this method to remove the
+  /// most recently incorporated function from the SlotMachine. This
+  /// will reset the state of the machine back to just the module contents.
+  void purgeFunction();
+
+/// @}
+/// @name Implementation Details
+/// @{
+private:
+  /// This function does the actual initialization.
+  inline void initialize();
+
+  /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
+  void CreateModuleSlot(const GlobalValue *V);
+  
+  /// CreateFunctionSlot - Insert the specified Value* into the slot table.
+  void CreateFunctionSlot(const Value *V);
+
+  /// Add all of the module level global variables (and their initializers)
+  /// and function declarations, but not the contents of those functions.
+  void processModule();
+
+  /// Add all of the functions arguments, basic blocks, and instructions
+  void processFunction();
+
+  SlotMachine(const SlotMachine &);  // DO NOT IMPLEMENT
+  void operator=(const SlotMachine &);  // DO NOT IMPLEMENT
+
+/// @}
+/// @name Data
+/// @{
+public:
+
+  /// @brief The module for which we are holding slot numbers
+  const Module* TheModule;
+
+  /// @brief The function for which we are holding slot numbers
+  const Function* TheFunction;
+  bool FunctionProcessed;
+
+  /// @brief The TypePlanes map for the module level data
+  ValueMap mMap;
+  unsigned mNext;
+
+  /// @brief The TypePlanes map for the function level data
+  ValueMap fMap;
+  unsigned fNext;
+
+/// @}
+
+};
+
+}  // end namespace llvm
 
+char PrintModulePass::ID = 0;
 static RegisterPass<PrintModulePass>
-X("printm", "Print module to stderr",PassInfo::Analysis|PassInfo::Optimization);
+X("printm", "Print module to stderr");
+char PrintFunctionPass::ID = 0;
 static RegisterPass<PrintFunctionPass>
-Y("print","Print function to stderr",PassInfo::Analysis|PassInfo::Optimization);
+Y("print","Print function to stderr");
 
-static void WriteAsOperandInternal(std::ostream &Out, const Value *V, 
-                                   bool PrintName,
-                                 std::map<const Type *, std::string> &TypeTable,
-                                   SlotCalculator *Table);
+static void WriteAsOperandInternal(std::ostream &Out, const Value *V,
+                               std::map<const Type *, std::string> &TypeTable,
+                                   SlotMachine *Machine);
 
 static const Module *getModuleFromVal(const Value *V) {
   if (const Argument *MA = dyn_cast<Argument>(V))
@@ -48,106 +160,159 @@ static const Module *getModuleFromVal(const Value *V) {
   return 0;
 }
 
-static SlotCalculator *createSlotCalculator(const Value *V) {
-  assert(!isa<Type>(V) && "Can't create an SC for a type!");
+static SlotMachine *createSlotMachine(const Value *V) {
   if (const Argument *FA = dyn_cast<Argument>(V)) {
-    return new SlotCalculator(FA->getParent(), true);
+    return new SlotMachine(FA->getParent());
   } else if (const Instruction *I = dyn_cast<Instruction>(V)) {
-    return new SlotCalculator(I->getParent()->getParent(), true);
+    return new SlotMachine(I->getParent()->getParent());
   } else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V)) {
-    return new SlotCalculator(BB->getParent(), true);
+    return new SlotMachine(BB->getParent());
   } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)){
-    return new SlotCalculator(GV->getParent(), true);
+    return new SlotMachine(GV->getParent());
+  } else if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(V)){
+    return new SlotMachine(GA->getParent());    
   } else if (const Function *Func = dyn_cast<Function>(V)) {
-    return new SlotCalculator(Func, true);
+    return new SlotMachine(Func);
   }
   return 0;
 }
 
-// getLLVMName - Turn the specified string into an 'LLVM name', which is either
-// prefixed with % (if the string only contains simple characters) or is
-// surrounded with ""'s (if it has special chars in it).
-static std::string getLLVMName(const std::string &Name) {
-  assert(!Name.empty() && "Cannot get empty name!");
-
-  // First character cannot start with a number...
-  if (Name[0] >= '0' && Name[0] <= '9')
-    return "\"" + Name + "\"";
-
-  // Scan to see if we have any characters that are not on the "white list"
+/// NameNeedsQuotes - Return true if the specified llvm name should be wrapped
+/// with ""'s.
+static std::string QuoteNameIfNeeded(const std::string &Name) {
+  std::string result;
+  bool needsQuotes = Name[0] >= '0' && Name[0] <= '9';
+  // Scan the name to see if it needs quotes and to replace funky chars with
+  // their octal equivalent.
   for (unsigned i = 0, e = Name.size(); i != e; ++i) {
     char C = Name[i];
     assert(C != '"' && "Illegal character in LLVM value name!");
-    if ((C < 'a' || C > 'z') && (C < 'A' || C > 'Z') && (C < '0' || C > '9') &&
-        C != '-' && C != '.' && C != '_')
-      return "\"" + Name + "\"";
+    if (isalnum(C) || C == '-' || C == '.' || C == '_')
+      result += C;
+    else if (C == '\\')  {
+      needsQuotes = true;
+      result += "\\\\";
+    } else if (isprint(C)) {
+      needsQuotes = true;
+      result += C;
+    } else {
+      needsQuotes = true;
+      result += "\\";
+      char hex1 = (C >> 4) & 0x0F;
+      if (hex1 < 10)
+        result += hex1 + '0';
+      else 
+        result += hex1 - 10 + 'A';
+      char hex2 = C & 0x0F;
+      if (hex2 < 10)
+        result += hex2 + '0';
+      else 
+        result += hex2 - 10 + 'A';
+    }
   }
-  
-  // If we get here, then the identifier is legal to use as a "VarID".
-  return "%"+Name;
+  if (needsQuotes) {
+    result.insert(0,"\"");
+    result += '"';
+  }
+  return result;
 }
 
+enum PrefixType {
+  GlobalPrefix,
+  LabelPrefix,
+  LocalPrefix
+};
 
-// If the module has a symbol table, take all global types and stuff their
-// names into the TypeNames map.
-//
+/// getLLVMName - Turn the specified string into an 'LLVM name', which is either
+/// prefixed with % (if the string only contains simple characters) or is
+/// surrounded with ""'s (if it has special chars in it).
+static std::string getLLVMName(const std::string &Name, PrefixType Prefix) {
+  assert(!Name.empty() && "Cannot get empty name!");
+  switch (Prefix) {
+  default: assert(0 && "Bad prefix!");
+  case GlobalPrefix: return '@' + QuoteNameIfNeeded(Name);
+  case LabelPrefix:  return QuoteNameIfNeeded(Name);
+  case LocalPrefix:  return '%' + QuoteNameIfNeeded(Name);
+  }      
+}
+
+
+/// fillTypeNameTable - If the module has a symbol table, take all global types
+/// and stuff their names into the TypeNames map.
+///
 static void fillTypeNameTable(const Module *M,
                               std::map<const Type *, std::string> &TypeNames) {
   if (!M) return;
-  const SymbolTable &ST = M->getSymbolTable();
-  SymbolTable::const_iterator PI = ST.find(Type::TypeTy);
-  if (PI != ST.end()) {
-    SymbolTable::type_const_iterator I = PI->second.begin();
-    for (; I != PI->second.end(); ++I) {
-      // As a heuristic, don't insert pointer to primitive types, because
-      // they are used too often to have a single useful name.
-      //
-      const Type *Ty = cast<Type>(I->second);
-      if (!isa<PointerType>(Ty) ||
-          !cast<PointerType>(Ty)->getElementType()->isPrimitiveType())
-        TypeNames.insert(std::make_pair(Ty, getLLVMName(I->first)));
-    }
+  const TypeSymbolTable &ST = M->getTypeSymbolTable();
+  TypeSymbolTable::const_iterator TI = ST.begin();
+  for (; TI != ST.end(); ++TI) {
+    // As a heuristic, don't insert pointer to primitive types, because
+    // they are used too often to have a single useful name.
+    //
+    const Type *Ty = cast<Type>(TI->second);
+    if (!isa<PointerType>(Ty) ||
+        !cast<PointerType>(Ty)->getElementType()->isPrimitiveType() ||
+        !cast<PointerType>(Ty)->getElementType()->isInteger() ||
+        isa<OpaqueType>(cast<PointerType>(Ty)->getElementType()))
+      TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first, LocalPrefix)));
   }
 }
 
 
 
-static std::string calcTypeName(const Type *Ty, 
-                                std::vector<const Type *> &TypeStack,
-                                std::map<const Type *, std::string> &TypeNames){
-  if (Ty->isPrimitiveType()) return Ty->getDescription();  // Base case
+static void calcTypeName(const Type *Ty,
+                         std::vector<const Type *> &TypeStack,
+                         std::map<const Type *, std::string> &TypeNames,
+                         std::string & Result){
+  if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))) {
+    Result += Ty->getDescription();  // Base case
+    return;
+  }
 
   // Check to see if the type is named.
   std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty);
-  if (I != TypeNames.end()) return I->second;
+  if (I != TypeNames.end()) {
+    Result += I->second;
+    return;
+  }
+
+  if (isa<OpaqueType>(Ty)) {
+    Result += "opaque";
+    return;
+  }
 
   // Check to see if the Type is already on the stack...
   unsigned Slot = 0, CurSize = TypeStack.size();
   while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type
 
-  // This is another base case for the recursion.  In this case, we know 
+  // This is another base case for the recursion.  In this case, we know
   // that we have looped back to a type that we have previously visited.
   // Generate the appropriate upreference to handle this.
-  // 
-  if (Slot < CurSize)
-    return "\\" + utostr(CurSize-Slot);       // Here's the upreference
+  if (Slot < CurSize) {
+    Result += "\\" + utostr(CurSize-Slot);     // Here's the upreference
+    return;
+  }
 
   TypeStack.push_back(Ty);    // Recursive case: Add us to the stack..
-  
-  std::string Result;
-  switch (Ty->getPrimitiveID()) {
+
+  switch (Ty->getTypeID()) {
+  case Type::IntegerTyID: {
+    unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+    Result += "i" + utostr(BitWidth);
+    break;
+  }
   case Type::FunctionTyID: {
     const FunctionType *FTy = cast<FunctionType>(Ty);
-    Result = calcTypeName(FTy->getReturnType(), TypeStack, TypeNames) + " (";
-    for (FunctionType::ParamTypes::const_iterator
-           I = FTy->getParamTypes().begin(),
-           E = FTy->getParamTypes().end(); I != E; ++I) {
-      if (I != FTy->getParamTypes().begin())
+    calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result);
+    Result += " (";
+    for (FunctionType::param_iterator I = FTy->param_begin(),
+         E = FTy->param_end(); I != E; ++I) {
+      if (I != FTy->param_begin())
         Result += ", ";
-      Result += calcTypeName(*I, TypeStack, TypeNames);
+      calcTypeName(*I, TypeStack, TypeNames, Result);
     }
     if (FTy->isVarArg()) {
-      if (!FTy->getParamTypes().empty()) Result += ", ";
+      if (FTy->getNumParams()) Result += ", ";
       Result += "...";
     }
     Result += ")";
@@ -155,48 +320,61 @@ static std::string calcTypeName(const Type *Ty,
   }
   case Type::StructTyID: {
     const StructType *STy = cast<StructType>(Ty);
-    Result = "{ ";
-    for (StructType::ElementTypes::const_iterator
-           I = STy->getElementTypes().begin(),
-           E = STy->getElementTypes().end(); I != E; ++I) {
-      if (I != STy->getElementTypes().begin())
+    if (STy->isPacked())
+      Result += '<';
+    Result += "{ ";
+    for (StructType::element_iterator I = STy->element_begin(),
+           E = STy->element_end(); I != E; ++I) {
+      if (I != STy->element_begin())
         Result += ", ";
-      Result += calcTypeName(*I, TypeStack, TypeNames);
+      calcTypeName(*I, TypeStack, TypeNames, Result);
     }
     Result += " }";
+    if (STy->isPacked())
+      Result += '>';
     break;
   }
   case Type::PointerTyID:
-    Result = calcTypeName(cast<PointerType>(Ty)->getElementType(), 
-                          TypeStack, TypeNames) + "*";
+    calcTypeName(cast<PointerType>(Ty)->getElementType(),
+                          TypeStack, TypeNames, Result);
+    Result += "*";
     break;
   case Type::ArrayTyID: {
     const ArrayType *ATy = cast<ArrayType>(Ty);
-    Result = "[" + utostr(ATy->getNumElements()) + " x ";
-    Result += calcTypeName(ATy->getElementType(), TypeStack, TypeNames) + "]";
+    Result += "[" + utostr(ATy->getNumElements()) + " x ";
+    calcTypeName(ATy->getElementType(), TypeStack, TypeNames, Result);
+    Result += "]";
+    break;
+  }
+  case Type::VectorTyID: {
+    const VectorType *PTy = cast<VectorType>(Ty);
+    Result += "<" + utostr(PTy->getNumElements()) + " x ";
+    calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result);
+    Result += ">";
     break;
   }
   case Type::OpaqueTyID:
-    Result = "opaque";
+    Result += "opaque";
     break;
   default:
-    Result = "<unrecognized-type>";
+    Result += "<unrecognized-type>";
+    break;
   }
 
   TypeStack.pop_back();       // Remove self from stack...
-  return Result;
 }
 
 
-// printTypeInt - The internal guts of printing out a type that has a
-// potentially named portion.
-//
+/// printTypeInt - The internal guts of printing out a type that has a
+/// potentially named portion.
+///
 static std::ostream &printTypeInt(std::ostream &Out, const Type *Ty,
                               std::map<const Type *, std::string> &TypeNames) {
   // Primitive types always print out their description, regardless of whether
   // they have been named or not.
   //
-  if (Ty->isPrimitiveType()) return Out << Ty->getDescription();
+  if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)))
+    return Out << Ty->getDescription();
 
   // Check to see if the type is named.
   std::map<const Type *, std::string>::iterator I = TypeNames.find(Ty);
@@ -207,180 +385,248 @@ static std::ostream &printTypeInt(std::ostream &Out, const Type *Ty,
   // names.
   //
   std::vector<const Type *> TypeStack;
-  std::string TypeName = calcTypeName(Ty, TypeStack, TypeNames);
+  std::string TypeName;
+  calcTypeName(Ty, TypeStack, TypeNames, TypeName);
   TypeNames.insert(std::make_pair(Ty, TypeName));//Cache type name for later use
-  return Out << TypeName;
+  return (Out << TypeName);
 }
 
 
-// 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;
-//
-std::ostream &WriteTypeSymbolic(std::ostream &Out, const Type *Ty,
-                                const Module *M) {
-  Out << " "; 
-
-  // If they want us to print out a type, attempt to make it symbolic if there
-  // is a symbol table in the module...
-  if (M) {
-    std::map<const Type *, std::string> TypeNames;
-    fillTypeNameTable(M, TypeNames);
-    
-    return printTypeInt(Out, Ty, TypeNames);
-  } else {
+/// 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
+///
+std::ostream &llvm::WriteTypeSymbolic(std::ostream &Out, const Type *Ty,
+                                      const Module *M) {
+  Out << ' ';
+
+  // If they want us to print out a type, but there is no context, we can't
+  // print it symbolically.
+  if (!M)
     return Out << Ty->getDescription();
+    
+  std::map<const Type *, std::string> TypeNames;
+  fillTypeNameTable(M, TypeNames);
+  return printTypeInt(Out, Ty, TypeNames);
+}
+
+// PrintEscapedString - Print each character of the specified string, escaping
+// it if it is not printable or if it is an escape char.
+static void PrintEscapedString(const std::string &Str, std::ostream &Out) {
+  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+    unsigned char C = Str[i];
+    if (isprint(C) && C != '"' && C != '\\') {
+      Out << C;
+    } else {
+      Out << '\\'
+          << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
+          << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
+    }
   }
 }
 
-static void WriteConstantInt(std::ostream &Out, const Constant *CV, 
-                             bool PrintName,
+static const char *getPredicateText(unsigned predicate) {
+  const char * pred = "unknown";
+  switch (predicate) {
+    case FCmpInst::FCMP_FALSE: pred = "false"; break;
+    case FCmpInst::FCMP_OEQ:   pred = "oeq"; break;
+    case FCmpInst::FCMP_OGT:   pred = "ogt"; break;
+    case FCmpInst::FCMP_OGE:   pred = "oge"; break;
+    case FCmpInst::FCMP_OLT:   pred = "olt"; break;
+    case FCmpInst::FCMP_OLE:   pred = "ole"; break;
+    case FCmpInst::FCMP_ONE:   pred = "one"; break;
+    case FCmpInst::FCMP_ORD:   pred = "ord"; break;
+    case FCmpInst::FCMP_UNO:   pred = "uno"; break;
+    case FCmpInst::FCMP_UEQ:   pred = "ueq"; break;
+    case FCmpInst::FCMP_UGT:   pred = "ugt"; break;
+    case FCmpInst::FCMP_UGE:   pred = "uge"; break;
+    case FCmpInst::FCMP_ULT:   pred = "ult"; break;
+    case FCmpInst::FCMP_ULE:   pred = "ule"; break;
+    case FCmpInst::FCMP_UNE:   pred = "une"; break;
+    case FCmpInst::FCMP_TRUE:  pred = "true"; break;
+    case ICmpInst::ICMP_EQ:    pred = "eq"; break;
+    case ICmpInst::ICMP_NE:    pred = "ne"; break;
+    case ICmpInst::ICMP_SGT:   pred = "sgt"; break;
+    case ICmpInst::ICMP_SGE:   pred = "sge"; break;
+    case ICmpInst::ICMP_SLT:   pred = "slt"; break;
+    case ICmpInst::ICMP_SLE:   pred = "sle"; break;
+    case ICmpInst::ICMP_UGT:   pred = "ugt"; break;
+    case ICmpInst::ICMP_UGE:   pred = "uge"; break;
+    case ICmpInst::ICMP_ULT:   pred = "ult"; break;
+    case ICmpInst::ICMP_ULE:   pred = "ule"; break;
+  }
+  return pred;
+}
+
+/// @brief Internal constant writer.
+static void WriteConstantInt(std::ostream &Out, const Constant *CV,
                              std::map<const Type *, std::string> &TypeTable,
-                             SlotCalculator *Table) {
-  if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
-    Out << (CB == ConstantBool::True ? "true" : "false");
-  } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) {
-    Out << CI->getValue();
-  } else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV)) {
-    Out << CI->getValue();
+                             SlotMachine *Machine) {
+  const int IndentSize = 4;
+  static std::string Indent = "\n";
+  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+    if (CI->getType() == Type::Int1Ty) 
+      Out << (CI->getZExtValue() ? "true" : "false");
+    else 
+      Out << CI->getValue().toStringSigned(10);
   } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
-    // We would like to output the FP constant value in exponential notation,
-    // but we cannot do this if doing so will lose precision.  Check here to
-    // make sure that we only output it in exponential format if we can parse
-    // the value back and get the same value.
-    //
-    std::string StrVal = ftostr(CFP->getValue());
-
-    // Check to make sure that the stringized number is not some string like
-    // "Inf" or NaN, that atof will accept, but the lexer will not.  Check that
-    // the string matches the "[-+]?[0-9]" regex.
-    //
-    if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
-        ((StrVal[0] == '-' || StrVal[0] == '+') &&
-         (StrVal[1] >= '0' && StrVal[1] <= '9')))
-      // Reparse stringized version!
-      if (atof(StrVal.c_str()) == CFP->getValue()) {
-        Out << StrVal; return;
+    if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble ||
+        &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) {
+      // We would like to output the FP constant value in exponential notation,
+      // but we cannot do this if doing so will lose precision.  Check here to
+      // make sure that we only output it in exponential format if we can parse
+      // the value back and get the same value.
+      //
+      bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble;
+      double Val = (isDouble) ? CFP->getValueAPF().convertToDouble() :
+                                CFP->getValueAPF().convertToFloat();
+      std::string StrVal = ftostr(CFP->getValueAPF());
+
+      // Check to make sure that the stringized number is not some string like
+      // "Inf" or NaN, that atof will accept, but the lexer will not.  Check
+      // that the string matches the "[-+]?[0-9]" regex.
+      //
+      if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+          ((StrVal[0] == '-' || StrVal[0] == '+') &&
+           (StrVal[1] >= '0' && StrVal[1] <= '9'))) {
+        // Reparse stringized version!
+        if (atof(StrVal.c_str()) == Val) {
+          Out << StrVal;
+          return;
+        }
+      }
+      // Otherwise we could not reparse it to exactly the same value, so we must
+      // output the string in hexadecimal format!
+      assert(sizeof(double) == sizeof(uint64_t) &&
+             "assuming that double is 64 bits!");
+      Out << "0x" << utohexstr(DoubleToBits(Val));
+    } else {
+      // Some form of long double.  These appear as a magic letter identifying
+      // the type, then a fixed number of hex digits.
+      Out << "0x";
+      if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended)
+        Out << 'K';
+      else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
+        Out << 'L';
+      else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
+        Out << 'M';
+      else
+        assert(0 && "Unsupported floating point type");
+      // api needed to prevent premature destruction
+      APInt api = CFP->getValueAPF().convertToAPInt();
+      const uint64_t* p = api.getRawData();
+      uint64_t word = *p;
+      int shiftcount=60;
+      int width = api.getBitWidth();
+      for (int j=0; j<width; j+=4, shiftcount-=4) {
+        unsigned int nibble = (word>>shiftcount) & 15;
+        if (nibble < 10)
+          Out << (unsigned char)(nibble + '0');
+        else
+          Out << (unsigned char)(nibble - 10 + 'A');
+        if (shiftcount == 0) {
+          word = *(++p);
+          shiftcount = 64;
+          if (width-j-4 < 64)
+            shiftcount = width-j-4;
+        }
       }
-    
-    // Otherwise we could not reparse it to exactly the same value, so we must
-    // output the string in hexadecimal format!
-    //
-    // Behave nicely in the face of C TBAA rules... see:
-    // http://www.nullstone.com/htmls/category/aliastyp.htm
-    //
-    double Val = CFP->getValue();
-    char *Ptr = (char*)&Val;
-    assert(sizeof(double) == sizeof(uint64_t) && sizeof(double) == 8 &&
-           "assuming that double is 64 bits!");
-    Out << "0x" << utohexstr(*(uint64_t*)Ptr);
-
-  } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
-    if (CA->getNumOperands() > 5 && CA->isNullValue()) {
-      Out << "zeroinitializer";
-      return;
     }
-
+  } else if (isa<ConstantAggregateZero>(CV)) {
+    Out << "zeroinitializer";
+  } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
     // As a special case, print the array as a string if it is an array of
     // ubytes or an array of sbytes with positive values.
-    // 
+    //
     const Type *ETy = CA->getType()->getElementType();
-    bool isString = (ETy == Type::SByteTy || ETy == Type::UByteTy);
-
-    if (ETy == Type::SByteTy)
-      for (unsigned i = 0; i < CA->getNumOperands(); ++i)
-        if (cast<ConstantSInt>(CA->getOperand(i))->getValue() < 0) {
-          isString = false;
-          break;
-        }
-
-    if (isString) {
+    if (CA->isString()) {
       Out << "c\"";
-      for (unsigned i = 0; i < CA->getNumOperands(); ++i) {
-        unsigned char C = cast<ConstantInt>(CA->getOperand(i))->getRawValue();
-        
-        if (isprint(C) && C != '"' && C != '\\') {
-          Out << C;
-        } else {
-          Out << '\\'
-              << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
-              << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
-        }
-      }
+      PrintEscapedString(CA->getAsString(), Out);
       Out << "\"";
 
     } else {                // Cannot output in string format...
-      Out << "[";
+      Out << '[';
       if (CA->getNumOperands()) {
-        Out << " ";
+        Out << ' ';
         printTypeInt(Out, ETy, TypeTable);
         WriteAsOperandInternal(Out, CA->getOperand(0),
-                               PrintName, TypeTable, Table);
+                               TypeTable, Machine);
         for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
           Out << ", ";
           printTypeInt(Out, ETy, TypeTable);
-          WriteAsOperandInternal(Out, CA->getOperand(i), PrintName,
-                                 TypeTable, Table);
+          WriteAsOperandInternal(Out, CA->getOperand(i), TypeTable, Machine);
         }
       }
       Out << " ]";
     }
   } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
-    if (CS->getNumOperands() > 5 && CS->isNullValue()) {
-      Out << "zeroinitializer";
-      return;
-    }
-
-    Out << "{";
-    if (CS->getNumOperands()) {
-      Out << " ";
+    if (CS->getType()->isPacked())
+      Out << '<';
+    Out << '{';
+    unsigned N = CS->getNumOperands();
+    if (N) {
+      if (N > 2) {
+        Indent += std::string(IndentSize, ' ');
+        Out << Indent;
+      } else {
+        Out << ' ';
+      }
       printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable);
 
-      WriteAsOperandInternal(Out, CS->getOperand(0),
-                             PrintName, TypeTable, Table);
+      WriteAsOperandInternal(Out, CS->getOperand(0), TypeTable, Machine);
 
-      for (unsigned i = 1; i < CS->getNumOperands(); i++) {
+      for (unsigned i = 1; i < N; i++) {
         Out << ", ";
+        if (N > 2) Out << Indent;
         printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable);
 
-        WriteAsOperandInternal(Out, CS->getOperand(i),
-                               PrintName, TypeTable, Table);
+        WriteAsOperandInternal(Out, CS->getOperand(i), TypeTable, Machine);
       }
+      if (N > 2) Indent.resize(Indent.size() - IndentSize);
     }
-
     Out << " }";
+    if (CS->getType()->isPacked())
+      Out << '>';
+  } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
+      const Type *ETy = CP->getType()->getElementType();
+      assert(CP->getNumOperands() > 0 &&
+             "Number of operands for a PackedConst must be > 0");
+      Out << '<';
+      Out << ' ';
+      printTypeInt(Out, ETy, TypeTable);
+      WriteAsOperandInternal(Out, CP->getOperand(0), TypeTable, Machine);
+      for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
+          Out << ", ";
+          printTypeInt(Out, ETy, TypeTable);
+          WriteAsOperandInternal(Out, CP->getOperand(i), TypeTable, Machine);
+      }
+      Out << " >";
   } else if (isa<ConstantPointerNull>(CV)) {
     Out << "null";
 
-  } else if (const ConstantPointerRef *PR = dyn_cast<ConstantPointerRef>(CV)) {
-    const GlobalValue *V = PR->getValue();
-    if (V->hasName()) {
-      Out << getLLVMName(V->getName());
-    } else if (Table) {
-      int Slot = Table->getValSlot(V);
-      if (Slot >= 0)
-        Out << "%" << Slot;
-      else
-        Out << "<pointer reference badref>";
-    } else {
-      Out << "<pointer reference without context info>";
-    }
+  } else if (isa<UndefValue>(CV)) {
+    Out << "undef";
 
   } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
-    Out << CE->getOpcodeName() << " (";
-    
+    Out << CE->getOpcodeName();
+    if (CE->isCompare())
+      Out << " " << getPredicateText(CE->getPredicate());
+    Out << " (";
+
     for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
       printTypeInt(Out, (*OI)->getType(), TypeTable);
-      WriteAsOperandInternal(Out, *OI, PrintName, TypeTable, Table);
+      WriteAsOperandInternal(Out, *OI, TypeTable, Machine);
       if (OI+1 != CE->op_end())
         Out << ", ";
     }
-    
-    if (CE->getOpcode() == Instruction::Cast) {
+
+    if (CE->isCast()) {
       Out << " to ";
       printTypeInt(Out, CE->getType(), TypeTable);
     }
-    Out << ")";
+
+    Out << ')';
 
   } else {
     Out << "<placeholder or erroneous Constant>";
@@ -388,51 +634,68 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
 }
 
 
-// WriteAsOperand - Write the name of the specified value out to the specified
-// ostream.  This can be useful when you just want to print int %reg126, not the
-// whole instruction that generated it.
-//
-static void WriteAsOperandInternal(std::ostream &Out, const Value *V, 
-                                   bool PrintName,
+/// WriteAsOperand - Write the name of the specified value out to the specified
+/// ostream.  This can be useful when you just want to print int %reg126, not
+/// the whole instruction that generated it.
+///
+static void WriteAsOperandInternal(std::ostream &Out, const Value *V,
                                   std::map<const Type*, std::string> &TypeTable,
-                                   SlotCalculator *Table) {
-  Out << " ";
-  if (PrintName && V->hasName()) {
-    Out << getLLVMName(V->getName());
-  } else {
-    if (const Constant *CV = dyn_cast<Constant>(V)) {
-      WriteConstantInt(Out, CV, PrintName, TypeTable, Table);
+                                   SlotMachine *Machine) {
+  Out << ' ';
+  if (V->hasName())
+    Out << getLLVMName(V->getName(),
+                       isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
+  else {
+    const Constant *CV = dyn_cast<Constant>(V);
+    if (CV && !isa<GlobalValue>(CV)) {
+      WriteConstantInt(Out, CV, TypeTable, Machine);
+    } else if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
+      Out << "asm ";
+      if (IA->hasSideEffects())
+        Out << "sideeffect ";
+      Out << '"';
+      PrintEscapedString(IA->getAsmString(), Out);
+      Out << "\", \"";
+      PrintEscapedString(IA->getConstraintString(), Out);
+      Out << '"';
     } else {
+      char Prefix = '%';
       int Slot;
-      if (Table) {
-       Slot = Table->getValSlot(V);
+      if (Machine) {
+        if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+          Slot = Machine->getGlobalSlot(GV);
+          Prefix = '@';
+        } else {
+          Slot = Machine->getLocalSlot(V);
+        }
       } else {
-        if (const Type *Ty = dyn_cast<Type>(V)) {
-          Out << Ty->getDescription();
-          return;
+        Machine = createSlotMachine(V);
+        if (Machine) {
+          if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+            Slot = Machine->getGlobalSlot(GV);
+            Prefix = '@';
+          } else {
+            Slot = Machine->getLocalSlot(V);
+          }
+        } else {
+          Slot = -1;
         }
-
-        Table = createSlotCalculator(V);
-        if (Table == 0) { Out << "BAD VALUE TYPE!"; return; }
-
-       Slot = Table->getValSlot(V);
-       delete Table;
+        delete Machine;
       }
-      if (Slot >= 0)  Out << "%" << Slot;
-      else if (PrintName)
-        Out << "<badref>";     // Not embeded into a location?
+      if (Slot != -1)
+        Out << Prefix << Slot;
+      else
+        Out << "<badref>";
     }
   }
 }
 
-
-
-// WriteAsOperand - Write the name of the specified value out to the specified
-// ostream.  This can be useful when you just want to print int %reg126, not the
-// whole instruction that generated it.
-//
-std::ostream &WriteAsOperand(std::ostream &Out, const Value *V, bool PrintType, 
-                             bool PrintName, const Module *Context) {
+/// WriteAsOperand - Write the name of the specified value out to the specified
+/// ostream.  This can be useful when you just want to print int %reg126, not
+/// the whole instruction that generated it.
+///
+std::ostream &llvm::WriteAsOperand(std::ostream &Out, const Value *V,
+                                   bool PrintType, const Module *Context) {
   std::map<const Type *, std::string> TypeNames;
   if (Context == 0) Context = getModuleFromVal(V);
 
@@ -441,21 +704,24 @@ std::ostream &WriteAsOperand(std::ostream &Out, const Value *V, bool PrintType,
 
   if (PrintType)
     printTypeInt(Out, V->getType(), TypeNames);
-  
-  WriteAsOperandInternal(Out, V, PrintName, TypeNames, 0);
+
+  WriteAsOperandInternal(Out, V, TypeNames, 0);
   return Out;
 }
 
 
+namespace llvm {
 
 class AssemblyWriter {
   std::ostream &Out;
-  SlotCalculator &Table;
+  SlotMachine &Machine;
   const Module *TheModule;
   std::map<const Type *, std::string> TypeNames;
+  AssemblyAnnotationWriter *AnnotationWriter;
 public:
-  inline AssemblyWriter(std::ostream &o, SlotCalculator &Tab, const Module *M)
-    : Out(o), Table(Tab), TheModule(M) {
+  inline AssemblyWriter(std::ostream &o, SlotMachine &Mac, const Module *M,
+                        AssemblyAnnotationWriter *AAW)
+    : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) {
 
     // If the module has a symbol table, take all global types and stuff their
     // names into the TypeNames map.
@@ -463,23 +729,26 @@ public:
     fillTypeNameTable(M, TypeNames);
   }
 
-  inline void write(const Module *M)         { printModule(M);      }
-  inline void write(const GlobalVariable *G) { printGlobal(G);      }
-  inline void write(const Function *F)       { printFunction(F);    }
-  inline void write(const BasicBlock *BB)    { printBasicBlock(BB); }
+  inline void write(const Module *M)         { printModule(M);       }
+  inline void write(const GlobalVariable *G) { printGlobal(G);       }
+  inline void write(const GlobalAlias *G)    { printAlias(G);        }
+  inline void write(const Function *F)       { printFunction(F);     }
+  inline void write(const BasicBlock *BB)    { printBasicBlock(BB);  }
   inline void write(const Instruction *I)    { printInstruction(*I); }
-  inline void write(const Constant *CPV)     { printConstant(CPV);  }
-  inline void write(const Type *Ty)          { printType(Ty);       }
+  inline void write(const Type *Ty)          { printType(Ty);        }
 
-  void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
+  void writeOperand(const Value *Op, bool PrintType);
+  void writeParamOperand(const Value *Operand, uint16_t Attrs);
 
-private :
+  const Module* getModule() { return TheModule; }
+
+private:
   void printModule(const Module *M);
-  void printSymbolTable(const SymbolTable &ST);
-  void printConstant(const Constant *CPV);
+  void printTypeSymbolTable(const TypeSymbolTable &ST);
   void printGlobal(const GlobalVariable *GV);
+  void printAlias(const GlobalAlias *GV);
   void printFunction(const Function *F);
-  void printArgument(const Argument *FA);
+  void printArgument(const Argument *FA, uint16_t ParamAttrs);
   void printBasicBlock(const BasicBlock *BB);
   void printInstruction(const Instruction &I);
 
@@ -499,42 +768,51 @@ private :
   // which slot it occupies.
   void printInfoComment(const Value &V);
 };
+}  // end of llvm namespace
 
-
-// printTypeAtLeastOneLevel - Print out one level of the possibly complex type
-// without considering any symbolic types that we may have equal to it.
-//
+/// printTypeAtLeastOneLevel - Print out one level of the possibly complex type
+/// without considering any symbolic types that we may have equal to it.
+///
 std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
-  if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
-    printType(FTy->getReturnType()) << " (";
-    for (FunctionType::ParamTypes::const_iterator
-           I = FTy->getParamTypes().begin(),
-           E = FTy->getParamTypes().end(); I != E; ++I) {
-      if (I != FTy->getParamTypes().begin())
+  if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
+    Out << "i" << utostr(ITy->getBitWidth());
+  else if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
+    printType(FTy->getReturnType());
+    Out << " (";
+    for (FunctionType::param_iterator I = FTy->param_begin(),
+           E = FTy->param_end(); I != E; ++I) {
+      if (I != FTy->param_begin())
         Out << ", ";
       printType(*I);
     }
     if (FTy->isVarArg()) {
-      if (!FTy->getParamTypes().empty()) Out << ", ";
+      if (FTy->getNumParams()) Out << ", ";
       Out << "...";
     }
-    Out << ")";
+    Out << ')';
   } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+    if (STy->isPacked())
+      Out << '<';
     Out << "{ ";
-    for (StructType::ElementTypes::const_iterator
-           I = STy->getElementTypes().begin(),
-           E = STy->getElementTypes().end(); I != E; ++I) {
-      if (I != STy->getElementTypes().begin())
+    for (StructType::element_iterator I = STy->element_begin(),
+           E = STy->element_end(); I != E; ++I) {
+      if (I != STy->element_begin())
         Out << ", ";
       printType(*I);
     }
     Out << " }";
+    if (STy->isPacked())
+      Out << '>';
   } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
-    printType(PTy->getElementType()) << "*";
+    printType(PTy->getElementType()) << '*';
   } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
-    Out << "[" << ATy->getNumElements() << " x ";
-    printType(ATy->getElementType()) << "]";
-  } else if (const OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
+    Out << '[' << ATy->getNumElements() << " x ";
+    printType(ATy->getElementType()) << ']';
+  } else if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) {
+    Out << '<' << PTy->getNumElements() << " x ";
+    printType(PTy->getElementType()) << '>';
+  }
+  else if (isa<OpaqueType>(Ty)) {
     Out << "opaque";
   } else {
     if (!Ty->isPrimitiveType())
@@ -545,142 +823,303 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
 }
 
 
-void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, 
-                                 bool PrintName) {
-  if (PrintType) { Out << " "; printType(Operand->getType()); }
-  WriteAsOperandInternal(Out, Operand, PrintName, TypeNames, &Table);
+void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
+  if (Operand == 0) {
+    Out << "<null operand!>";
+  } else {
+    if (PrintType) { Out << ' '; printType(Operand->getType()); }
+    WriteAsOperandInternal(Out, Operand, TypeNames, &Machine);
+  }
 }
 
+void AssemblyWriter::writeParamOperand(const Value *Operand, uint16_t Attrs) {
+  if (Operand == 0) {
+    Out << "<null operand!>";
+  } else {
+    Out << ' ';
+    // Print the type
+    printType(Operand->getType());
+    // Print parameter attributes list
+    if (Attrs != ParamAttr::None)
+      Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs);
+    // Print the operand
+    WriteAsOperandInternal(Out, Operand, TypeNames, &Machine);
+  }
+}
 
 void AssemblyWriter::printModule(const Module *M) {
-  switch (M->getEndianness()) {
-  case Module::LittleEndian: Out << "target endian = little\n"; break;
-  case Module::BigEndian:    Out << "target endian = big\n";    break;
-  case Module::AnyEndianness: break;
-  }
-  switch (M->getPointerSize()) {
-  case Module::Pointer32:    Out << "target pointersize = 32\n"; break;
-  case Module::Pointer64:    Out << "target pointersize = 64\n"; break;
-  case Module::AnyPointerSize: break;
+  if (!M->getModuleIdentifier().empty() &&
+      // Don't print the ID if it will start a new line (which would
+      // require a comment char before it).
+      M->getModuleIdentifier().find('\n') == std::string::npos)
+    Out << "; ModuleID = '" << M->getModuleIdentifier() << "'\n";
+
+  if (!M->getDataLayout().empty())
+    Out << "target datalayout = \"" << M->getDataLayout() << "\"\n";
+  if (!M->getTargetTriple().empty())
+    Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
+
+  if (!M->getModuleInlineAsm().empty()) {
+    // Split the string into lines, to make it easier to read the .ll file.
+    std::string Asm = M->getModuleInlineAsm();
+    size_t CurPos = 0;
+    size_t NewLine = Asm.find_first_of('\n', CurPos);
+    while (NewLine != std::string::npos) {
+      // We found a newline, print the portion of the asm string from the
+      // last newline up to this newline.
+      Out << "module asm \"";
+      PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.begin()+NewLine),
+                         Out);
+      Out << "\"\n";
+      CurPos = NewLine+1;
+      NewLine = Asm.find_first_of('\n', CurPos);
+    }
+    Out << "module asm \"";
+    PrintEscapedString(std::string(Asm.begin()+CurPos, Asm.end()), Out);
+    Out << "\"\n";
   }
   
-  // Loop over the symbol table, emitting all named constants...
-  printSymbolTable(M->getSymbolTable());
-  
-  for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I)
-    printGlobal(I);
+  // Loop over the dependent libraries and emit them.
+  Module::lib_iterator LI = M->lib_begin();
+  Module::lib_iterator LE = M->lib_end();
+  if (LI != LE) {
+    Out << "deplibs = [ ";
+    while (LI != LE) {
+      Out << '"' << *LI << '"';
+      ++LI;
+      if (LI != LE)
+        Out << ", ";
+    }
+    Out << " ]\n";
+  }
 
-  Out << "\nimplementation   ; Functions:\n";
+  // Loop over the symbol table, emitting all named constants.
+  printTypeSymbolTable(M->getTypeSymbolTable());
+
+  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
+       I != E; ++I)
+    printGlobal(I);
   
-  // Output all of the functions...
+  // Output all aliases.
+  if (!M->alias_empty()) Out << "\n";
+  for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
+       I != E; ++I)
+    printAlias(I);
+
+  // Output all of the functions.
   for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
     printFunction(I);
 }
 
 void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
-  if (GV->hasName()) Out << getLLVMName(GV->getName()) << " = ";
+  if (GV->hasName()) Out << getLLVMName(GV->getName(), GlobalPrefix) << " = ";
 
-  if (!GV->hasInitializer()) 
-    Out << "external ";
-  else
+  if (!GV->hasInitializer())
     switch (GV->getLinkage()) {
-    case GlobalValue::InternalLinkage: Out << "internal "; break;
-    case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
-    case GlobalValue::AppendingLinkage: Out << "appending "; break;
-    case GlobalValue::ExternalLinkage: break;
+     case GlobalValue::DLLImportLinkage:   Out << "dllimport "; break;
+     case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
+     default: Out << "external "; break;
+    } else {
+    switch (GV->getLinkage()) {
+    case GlobalValue::InternalLinkage:     Out << "internal "; break;
+    case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
+    case GlobalValue::WeakLinkage:         Out << "weak "; break;
+    case GlobalValue::AppendingLinkage:    Out << "appending "; break;
+    case GlobalValue::DLLImportLinkage:    Out << "dllimport "; break;
+    case GlobalValue::DLLExportLinkage:    Out << "dllexport "; break;     
+    case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
+    case GlobalValue::ExternalLinkage:     break;
+    case GlobalValue::GhostLinkage:
+      cerr << "GhostLinkage not allowed in AsmWriter!\n";
+      abort();
+    }
+    switch (GV->getVisibility()) {
+    default: assert(0 && "Invalid visibility style!");
+    case GlobalValue::DefaultVisibility: break;
+    case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+    case GlobalValue::ProtectedVisibility: Out << "protected "; break;
     }
+  }
 
+  if (GV->isThreadLocal()) Out << "thread_local ";
   Out << (GV->isConstant() ? "constant " : "global ");
   printType(GV->getType()->getElementType());
 
-  if (GV->hasInitializer())
-    writeOperand(GV->getInitializer(), false, false);
+  if (GV->hasInitializer()) {
+    Constant* C = cast<Constant>(GV->getInitializer());
+    assert(C &&  "GlobalVar initializer isn't constant?");
+    writeOperand(GV->getInitializer(), false);
+  }
+
+  if (GV->hasSection())
+    Out << ", section \"" << GV->getSection() << '"';
+  if (GV->getAlignment())
+    Out << ", align " << GV->getAlignment();
 
   printInfoComment(*GV);
   Out << "\n";
 }
 
+void AssemblyWriter::printAlias(const GlobalAlias *GA) {
+  Out << getLLVMName(GA->getName(), GlobalPrefix) << " = ";
+  switch (GA->getVisibility()) {
+  default: assert(0 && "Invalid visibility style!");
+  case GlobalValue::DefaultVisibility: break;
+  case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+  case GlobalValue::ProtectedVisibility: Out << "protected "; break;
+  }
+
+  Out << "alias ";
 
-// printSymbolTable - Run through symbol table looking for named constants
-// if a named constant is found, emit it's declaration...
-//
-void AssemblyWriter::printSymbolTable(const SymbolTable &ST) {
-  for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
-    SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
-    SymbolTable::type_const_iterator End = ST.type_end(TI->first);
+  switch (GA->getLinkage()) {
+  case GlobalValue::WeakLinkage: Out << "weak "; break;
+  case GlobalValue::InternalLinkage: Out << "internal "; break;
+  case GlobalValue::ExternalLinkage: break;
+  default:
+   assert(0 && "Invalid alias linkage");
+  }
+  
+  const Constant *Aliasee = GA->getAliasee();
     
-    for (; I != End; ++I) {
-      const Value *V = I->second;
-      if (const Constant *CPV = dyn_cast<Constant>(V)) {
-       printConstant(CPV);
-      } else if (const Type *Ty = dyn_cast<Type>(V)) {
-       Out << "\t" << getLLVMName(I->first) << " = type ";
-
-        // Make sure we print out at least one level of the type structure, so
-        // that we do not get %FILE = type %FILE
-        //
-        printTypeAtLeastOneLevel(Ty) << "\n";
-      }
-    }
+  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) {
+    printType(GV->getType());
+    Out << " " << getLLVMName(GV->getName(), GlobalPrefix);
+  } else if (const Function *F = dyn_cast<Function>(Aliasee)) {
+    printType(F->getFunctionType());
+    Out << "* ";
+
+    if (!F->getName().empty())
+      Out << getLLVMName(F->getName(), GlobalPrefix);
+    else
+      Out << "@\"\"";
+  } else {
+    const ConstantExpr *CE = 0;
+    if ((CE = dyn_cast<ConstantExpr>(Aliasee)) &&
+        (CE->getOpcode() == Instruction::BitCast)) {
+      writeOperand(CE, false);    
+    } else
+      assert(0 && "Unsupported aliasee");
   }
+  
+  printInfoComment(*GA);
+  Out << "\n";
 }
 
+void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
+  // Print the types.
+  for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
+       TI != TE; ++TI) {
+    Out << "\t" << getLLVMName(TI->first, LocalPrefix) << " = type ";
 
-// printConstant - Print out a constant pool entry...
-//
-void AssemblyWriter::printConstant(const Constant *CPV) {
-  // Don't print out unnamed constants, they will be inlined
-  if (!CPV->hasName()) return;
-
-  // Print out name...
-  Out << "\t" << getLLVMName(CPV->getName()) << " =";
-
-  // Write the value out now...
-  writeOperand(CPV, true, false);
-
-  printInfoComment(*CPV);
-  Out << "\n";
+    // Make sure we print out at least one level of the type structure, so
+    // that we do not get %FILE = type %FILE
+    //
+    printTypeAtLeastOneLevel(TI->second) << "\n";
+  }
 }
 
-// printFunction - Print all aspects of a function.
-//
+/// printFunction - Print all aspects of a function.
+///
 void AssemblyWriter::printFunction(const Function *F) {
   // Print out the return type and name...
   Out << "\n";
 
-  if (F->isExternal())
+  if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
+
+  if (F->isDeclaration())
     Out << "declare ";
   else
-    switch (F->getLinkage()) {
-    case GlobalValue::InternalLinkage: Out << "internal "; break;
-    case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
-    case GlobalValue::AppendingLinkage: Out << "appending "; break;
-    case GlobalValue::ExternalLinkage: break;
-    }
+    Out << "define ";
+    
+  switch (F->getLinkage()) {
+  case GlobalValue::InternalLinkage:     Out << "internal "; break;
+  case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
+  case GlobalValue::WeakLinkage:         Out << "weak "; break;
+  case GlobalValue::AppendingLinkage:    Out << "appending "; break;
+  case GlobalValue::DLLImportLinkage:    Out << "dllimport "; break;
+  case GlobalValue::DLLExportLinkage:    Out << "dllexport "; break;
+  case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;      
+  case GlobalValue::ExternalLinkage: break;
+  case GlobalValue::GhostLinkage:
+    cerr << "GhostLinkage not allowed in AsmWriter!\n";
+    abort();
+  }
+  switch (F->getVisibility()) {
+  default: assert(0 && "Invalid visibility style!");
+  case GlobalValue::DefaultVisibility: break;
+  case GlobalValue::HiddenVisibility: Out << "hidden "; break;
+  case GlobalValue::ProtectedVisibility: Out << "protected "; break;
+  }
 
-  printType(F->getReturnType()) << " ";
-  if (!F->getName().empty()) Out << getLLVMName(F->getName());
-  Out << "(";
-  Table.incorporateFunction(F);
+  // Print the calling convention.
+  switch (F->getCallingConv()) {
+  case CallingConv::C: break;   // default
+  case CallingConv::Fast:         Out << "fastcc "; break;
+  case CallingConv::Cold:         Out << "coldcc "; break;
+  case CallingConv::X86_StdCall:  Out << "x86_stdcallcc "; break;
+  case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break; 
+  default: Out << "cc" << F->getCallingConv() << " "; break;
+  }
 
-  // Loop over the arguments, printing them...
   const FunctionType *FT = F->getFunctionType();
+  const ParamAttrsList *Attrs = F->getParamAttrs();
+  printType(F->getReturnType()) << ' ';
+  if (!F->getName().empty())
+    Out << getLLVMName(F->getName(), GlobalPrefix);
+  else
+    Out << "@\"\"";
+  Out << '(';
+  Machine.incorporateFunction(F);
+
+  // Loop over the arguments, printing them...
 
-  for(Function::const_aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
-    printArgument(I);
+  unsigned Idx = 1;
+  if (!F->isDeclaration()) {
+    // If this isn't a declaration, print the argument names as well.
+    for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
+         I != E; ++I) {
+      // Insert commas as we go... the first arg doesn't get a comma
+      if (I != F->arg_begin()) Out << ", ";
+      printArgument(I, (Attrs ? Attrs->getParamAttrs(Idx)
+                              : uint16_t(ParamAttr::None)));
+      Idx++;
+    }
+  } else {
+    // Otherwise, print the types from the function type.
+    for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+      // Insert commas as we go... the first arg doesn't get a comma
+      if (i) Out << ", ";
+      
+      // Output type...
+      printType(FT->getParamType(i));
+      
+      unsigned ArgAttrs = ParamAttr::None;
+      if (Attrs) ArgAttrs = Attrs->getParamAttrs(i+1);
+      if (ArgAttrs != ParamAttr::None)
+        Out << ' ' << ParamAttrsList::getParamAttrsText(ArgAttrs);
+    }
+  }
 
   // Finish printing arguments...
   if (FT->isVarArg()) {
-    if (FT->getParamTypes().size()) Out << ", ";
+    if (FT->getNumParams()) Out << ", ";
     Out << "...";  // Output varargs portion of signature!
   }
-  Out << ")";
-
-  if (F->isExternal()) {
+  Out << ')';
+  if (Attrs && Attrs->getParamAttrs(0) != ParamAttr::None)
+    Out << ' ' << Attrs->getParamAttrsTextByIndex(0);
+  if (F->hasSection())
+    Out << " section \"" << F->getSection() << '"';
+  if (F->getAlignment())
+    Out << " align " << F->getAlignment();
+  if (F->hasCollector())
+    Out << " gc \"" << F->getCollector() << '"';
+
+  if (F->isDeclaration()) {
     Out << "\n";
   } else {
     Out << " {";
-  
+
     // Output all of its basic blocks... for the function
     for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I)
       printBasicBlock(I);
@@ -688,207 +1127,268 @@ void AssemblyWriter::printFunction(const Function *F) {
     Out << "}\n";
   }
 
-  Table.purgeFunction();
+  Machine.purgeFunction();
 }
 
-// printArgument - This member is called for every argument that 
-// is passed into the function.  Simply print it out
-//
-void AssemblyWriter::printArgument(const Argument *Arg) {
-  // Insert commas as we go... the first arg doesn't get a comma
-  if (Arg != &Arg->getParent()->afront()) Out << ", ";
-
+/// printArgument - This member is called for every argument that is passed into
+/// the function.  Simply print it out
+///
+void AssemblyWriter::printArgument(const Argument *Arg, uint16_t Attrs) {
   // Output type...
   printType(Arg->getType());
-  
+
+  // Output parameter attributes list
+  if (Attrs != ParamAttr::None)
+    Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs);
+
   // Output name, if available...
   if (Arg->hasName())
-    Out << " " << getLLVMName(Arg->getName());
-  else if (Table.getValSlot(Arg) < 0)
-    Out << "<badref>";
+    Out << ' ' << getLLVMName(Arg->getName(), LocalPrefix);
 }
 
-// printBasicBlock - This member is called for each basic block in a methd.
-//
+/// printBasicBlock - This member is called for each basic block in a method.
+///
 void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
   if (BB->hasName()) {              // Print out the label if it exists...
-    Out << "\n" << BB->getName() << ":";
+    Out << "\n" << getLLVMName(BB->getName(), LabelPrefix) << ':';
   } else if (!BB->use_empty()) {      // Don't print block # of no uses...
-    int Slot = Table.getValSlot(BB);
     Out << "\n; <label>:";
-    if (Slot >= 0) 
-      Out << Slot;         // Extra newline separates out label's
-    else 
-      Out << "<badref>"; 
+    int Slot = Machine.getLocalSlot(BB);
+    if (Slot != -1)
+      Out << Slot;
+    else
+      Out << "<badref>";
   }
-  
-  // Output predecessors for the block...
-  Out << "\t\t;";
-  pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB);
 
-  if (PI == PE) {
-    Out << " No predecessors!";
-  } else {
-    Out << " preds =";
-    writeOperand(*PI, false, true);
-    for (++PI; PI != PE; ++PI) {
-      Out << ",";
-      writeOperand(*PI, false, true);
+  if (BB->getParent() == 0)
+    Out << "\t\t; Error: Block without parent!";
+  else {
+    if (BB != &BB->getParent()->getEntryBlock()) {  // Not the entry block?
+      // Output predecessors for the block...
+      Out << "\t\t;";
+      pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB);
+
+      if (PI == PE) {
+        Out << " No predecessors!";
+      } else {
+        Out << " preds =";
+        writeOperand(*PI, false);
+        for (++PI; PI != PE; ++PI) {
+          Out << ',';
+          writeOperand(*PI, false);
+        }
+      }
     }
   }
-  
+
   Out << "\n";
 
+  if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
+
   // Output all of the instructions in the basic block...
   for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
     printInstruction(*I);
+
+  if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
 }
 
 
-// printInfoComment - Print a little comment after the instruction indicating
-// which slot it occupies.
-//
+/// printInfoComment - Print a little comment after the instruction indicating
+/// which slot it occupies.
+///
 void AssemblyWriter::printInfoComment(const Value &V) {
   if (V.getType() != Type::VoidTy) {
     Out << "\t\t; <";
-    printType(V.getType()) << ">";
+    printType(V.getType()) << '>';
 
     if (!V.hasName()) {
-      int Slot = Table.getValSlot(&V); // Print out the def slot taken...
-      if (Slot >= 0) Out << ":" << Slot;
-      else Out << ":<badref>";
+      int SlotNum;
+      if (const GlobalValue *GV = dyn_cast<GlobalValue>(&V))
+        SlotNum = Machine.getGlobalSlot(GV);
+      else
+        SlotNum = Machine.getLocalSlot(&V);
+      if (SlotNum == -1)
+        Out << ":<badref>";
+      else
+        Out << ':' << SlotNum; // Print out the def slot taken.
     }
-    Out << " [#uses=" << V.use_size() << "]";  // Output # uses
+    Out << " [#uses=" << V.getNumUses() << ']';  // Output # uses
   }
 }
 
-// printInstruction - This member is called for each Instruction in a methd.
-//
+// This member is called for each Instruction in a function..
 void AssemblyWriter::printInstruction(const Instruction &I) {
+  if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out);
+
   Out << "\t";
 
   // Print out name if it exists...
   if (I.hasName())
-    Out << getLLVMName(I.getName()) << " = ";
+    Out << getLLVMName(I.getName(), LocalPrefix) << " = ";
+
+  // If this is a volatile load or store, print out the volatile marker.
+  if ((isa<LoadInst>(I)  && cast<LoadInst>(I).isVolatile()) ||
+      (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile())) {
+      Out << "volatile ";
+  } else if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall()) {
+    // If this is a call, check if it's a tail call.
+    Out << "tail ";
+  }
 
   // Print out the opcode...
   Out << I.getOpcodeName();
 
+  // Print out the compare instruction predicates
+  if (const FCmpInst *FCI = dyn_cast<FCmpInst>(&I)) {
+    Out << " " << getPredicateText(FCI->getPredicate());
+  } else if (const ICmpInst *ICI = dyn_cast<ICmpInst>(&I)) {
+    Out << " " << getPredicateText(ICI->getPredicate());
+  }
+
   // Print out the type of the operands...
   const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0;
 
   // Special case conditional branches to swizzle the condition out to the front
   if (isa<BranchInst>(I) && I.getNumOperands() > 1) {
     writeOperand(I.getOperand(2), true);
-    Out << ",";
+    Out << ',';
     writeOperand(Operand, true);
-    Out << ",";
+    Out << ',';
     writeOperand(I.getOperand(1), true);
 
   } else if (isa<SwitchInst>(I)) {
     // Special case switch statement to get formatting nice and correct...
-    writeOperand(Operand        , true); Out << ",";
+    writeOperand(Operand        , true); Out << ',';
     writeOperand(I.getOperand(1), true); Out << " [";
 
     for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) {
       Out << "\n\t\t";
-      writeOperand(I.getOperand(op  ), true); Out << ",";
+      writeOperand(I.getOperand(op  ), true); Out << ',';
       writeOperand(I.getOperand(op+1), true);
     }
     Out << "\n\t]";
   } else if (isa<PHINode>(I)) {
-    Out << " ";
+    Out << ' ';
     printType(I.getType());
-    Out << " ";
+    Out << ' ';
 
     for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
       if (op) Out << ", ";
-      Out << "[";  
-      writeOperand(I.getOperand(op  ), false); Out << ",";
+      Out << '[';
+      writeOperand(I.getOperand(op  ), false); Out << ',';
       writeOperand(I.getOperand(op+1), false); Out << " ]";
     }
   } else if (isa<ReturnInst>(I) && !Operand) {
     Out << " void";
-  } else if (isa<CallInst>(I)) {
-    const PointerType  *PTy = cast<PointerType>(Operand->getType());
-    const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
-    const Type       *RetTy = FTy->getReturnType();
+  } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
+    // Print the calling convention being used.
+    switch (CI->getCallingConv()) {
+    case CallingConv::C: break;   // default
+    case CallingConv::Fast:  Out << " fastcc"; break;
+    case CallingConv::Cold:  Out << " coldcc"; break;
+    case CallingConv::X86_StdCall:  Out << " x86_stdcallcc"; break;
+    case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break; 
+    default: Out << " cc" << CI->getCallingConv(); break;
+    }
+
+    const PointerType    *PTy = cast<PointerType>(Operand->getType());
+    const FunctionType   *FTy = cast<FunctionType>(PTy->getElementType());
+    const Type         *RetTy = FTy->getReturnType();
+    const ParamAttrsList *PAL = CI->getParamAttrs();
 
     // If possible, print out the short form of the call instruction.  We can
     // only do this if the first argument is a pointer to a nonvararg function,
     // and if the return type is not a pointer to a function.
     //
     if (!FTy->isVarArg() &&
-        (!isa<PointerType>(RetTy) || 
+        (!isa<PointerType>(RetTy) ||
          !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
-      Out << " "; printType(RetTy);
+      Out << ' '; printType(RetTy);
       writeOperand(Operand, false);
     } else {
       writeOperand(Operand, true);
     }
-    Out << "(";
-    if (I.getNumOperands() > 1) writeOperand(I.getOperand(1), true);
-    for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; ++op) {
-      Out << ",";
-      writeOperand(I.getOperand(op), true);
+    Out << '(';
+    for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) {
+      if (op > 1)
+        Out << ',';
+      writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op) : 0);
     }
-
     Out << " )";
+    if (PAL && PAL->getParamAttrs(0) != ParamAttr::None)
+      Out << ' ' << PAL->getParamAttrsTextByIndex(0);
   } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
-    const PointerType  *PTy = cast<PointerType>(Operand->getType());
-    const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
-    const Type       *RetTy = FTy->getReturnType();
+    const PointerType    *PTy = cast<PointerType>(Operand->getType());
+    const FunctionType   *FTy = cast<FunctionType>(PTy->getElementType());
+    const Type         *RetTy = FTy->getReturnType();
+    const ParamAttrsList *PAL = II->getParamAttrs();
+
+    // Print the calling convention being used.
+    switch (II->getCallingConv()) {
+    case CallingConv::C: break;   // default
+    case CallingConv::Fast:  Out << " fastcc"; break;
+    case CallingConv::Cold:  Out << " coldcc"; break;
+    case CallingConv::X86_StdCall:  Out << "x86_stdcallcc "; break;
+    case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break;
+    default: Out << " cc" << II->getCallingConv(); break;
+    }
 
     // If possible, print out the short form of the invoke instruction. We can
     // only do this if the first argument is a pointer to a nonvararg function,
     // and if the return type is not a pointer to a function.
     //
     if (!FTy->isVarArg() &&
-        (!isa<PointerType>(RetTy) || 
+        (!isa<PointerType>(RetTy) ||
          !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
-      Out << " "; printType(RetTy);
+      Out << ' '; printType(RetTy);
       writeOperand(Operand, false);
     } else {
       writeOperand(Operand, true);
     }
 
-    Out << "(";
-    if (I.getNumOperands() > 3) writeOperand(I.getOperand(3), true);
-    for (unsigned op = 4, Eop = I.getNumOperands(); op < Eop; ++op) {
-      Out << ",";
-      writeOperand(I.getOperand(op), true);
+    Out << '(';
+    for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) {
+      if (op > 3)
+        Out << ',';
+      writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op-2) : 0);
     }
 
-    Out << " )\n\t\t\tto";
+    Out << " )";
+    if (PAL && PAL->getParamAttrs(0) != ParamAttr::None)
+      Out << " " << PAL->getParamAttrsTextByIndex(0);
+    Out << "\n\t\t\tto";
     writeOperand(II->getNormalDest(), true);
-    Out << " except";
-    writeOperand(II->getExceptionalDest(), true);
+    Out << " unwind";
+    writeOperand(II->getUnwindDest(), true);
 
   } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) {
-    Out << " ";
+    Out << ' ';
     printType(AI->getType()->getElementType());
     if (AI->isArrayAllocation()) {
-      Out << ",";
+      Out << ',';
       writeOperand(AI->getArraySize(), true);
     }
+    if (AI->getAlignment()) {
+      Out << ", align " << AI->getAlignment();
+    }
   } else if (isa<CastInst>(I)) {
-    writeOperand(Operand, true);
+    if (Operand) writeOperand(Operand, true);   // Work with broken code
     Out << " to ";
     printType(I.getType());
-  } else if (isa<VarArgInst>(I)) {
-    writeOperand(Operand, true);
+  } else if (isa<VAArgInst>(I)) {
+    if (Operand) writeOperand(Operand, true);   // Work with broken code
     Out << ", ";
     printType(I.getType());
   } else if (Operand) {   // Print the normal way...
 
-    // PrintAllTypes - Instructions who have operands of all the same type 
+    // PrintAllTypes - Instructions who have operands of all the same type
     // omit the type from all but the first operand.  If the instruction has
     // different type operands (for example br), then they are all printed.
     bool PrintAllTypes = false;
     const Type *TheType = Operand->getType();
 
-    // Shift Left & Right print both types even for Ubyte LHS
-    if (isa<ShiftInst>(I)) {
+    // Select, Store and ShuffleVector always print all types.
+    if (isa<SelectInst>(I) || isa<StoreInst>(I) || isa<ShuffleVectorInst>(I)) {
       PrintAllTypes = true;
     } else {
       for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
@@ -899,17 +1399,24 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
         }
       }
     }
-    
+
     if (!PrintAllTypes) {
-      Out << " ";
+      Out << ' ';
       printType(TheType);
     }
 
     for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) {
-      if (i) Out << ",";
+      if (i) Out << ',';
       writeOperand(I.getOperand(i), PrintAllTypes);
     }
   }
+  
+  // Print post operand alignment for load/store
+  if (isa<LoadInst>(I) && cast<LoadInst>(I).getAlignment()) {
+    Out << ", align " << cast<LoadInst>(I).getAlignment();
+  } else if (isa<StoreInst>(I) && cast<StoreInst>(I).getAlignment()) {
+    Out << ", align " << cast<StoreInst>(I).getAlignment();
+  }
 
   printInfoComment(I);
   Out << "\n";
@@ -920,37 +1427,46 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
 //                       External Interface declarations
 //===----------------------------------------------------------------------===//
 
-
-void Module::print(std::ostream &o) const {
-  SlotCalculator SlotTable(this, true);
-  AssemblyWriter W(o, SlotTable, this);
+void Module::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
+  SlotMachine SlotTable(this);
+  AssemblyWriter W(o, SlotTable, this, AAW);
   W.write(this);
 }
 
 void GlobalVariable::print(std::ostream &o) const {
-  SlotCalculator SlotTable(getParent(), true);
-  AssemblyWriter W(o, SlotTable, getParent());
+  SlotMachine SlotTable(getParent());
+  AssemblyWriter W(o, SlotTable, getParent(), 0);
+  W.write(this);
+}
+
+void GlobalAlias::print(std::ostream &o) const {
+  SlotMachine SlotTable(getParent());
+  AssemblyWriter W(o, SlotTable, getParent(), 0);
   W.write(this);
 }
 
-void Function::print(std::ostream &o) const {
-  SlotCalculator SlotTable(getParent(), true);
-  AssemblyWriter W(o, SlotTable, getParent());
+void Function::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
+  SlotMachine SlotTable(getParent());
+  AssemblyWriter W(o, SlotTable, getParent(), AAW);
 
   W.write(this);
 }
 
-void BasicBlock::print(std::ostream &o) const {
-  SlotCalculator SlotTable(getParent(), true);
-  AssemblyWriter W(o, SlotTable, 
-                   getParent() ? getParent()->getParent() : 0);
+void InlineAsm::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
+  WriteAsOperand(o, this, true, 0);
+}
+
+void BasicBlock::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
+  SlotMachine SlotTable(getParent());
+  AssemblyWriter W(o, SlotTable,
+                   getParent() ? getParent()->getParent() : 0, AAW);
   W.write(this);
 }
 
-void Instruction::print(std::ostream &o) const {
+void Instruction::print(std::ostream &o, AssemblyAnnotationWriter *AAW) const {
   const Function *F = getParent() ? getParent()->getParent() : 0;
-  SlotCalculator SlotTable(F, true);
-  AssemblyWriter W(o, SlotTable, F ? F->getParent() : 0);
+  SlotMachine SlotTable(F);
+  AssemblyWriter W(o, SlotTable, F ? F->getParent() : 0, AAW);
 
   W.write(this);
 }
@@ -958,19 +1474,13 @@ void Instruction::print(std::ostream &o) const {
 void Constant::print(std::ostream &o) const {
   if (this == 0) { o << "<null> constant value\n"; return; }
 
-  // Handle CPR's special, because they have context information...
-  if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(this)) {
-    CPR->getValue()->print(o);  // Print as a global value, with context info.
-    return;
-  }
-
-  o << " " << getType()->getDescription() << " ";
+  o << ' ' << getType()->getDescription() << ' ';
 
   std::map<const Type *, std::string> TypeTable;
-  WriteConstantInt(o, this, false, TypeTable, 0);
+  WriteConstantInt(o, this, TypeTable, 0);
 }
 
-void Type::print(std::ostream &o) const { 
+void Type::print(std::ostream &o) const {
   if (this == 0)
     o << "<null Type>";
   else
@@ -978,41 +1488,181 @@ void Type::print(std::ostream &o) const {
 }
 
 void Argument::print(std::ostream &o) const {
-  o << getType() << " " << getName();
+  WriteAsOperand(o, this, true, getParent() ? getParent()->getParent() : 0);
 }
 
-void Value::dump() const { print(std::cerr); }
+// Value::dump - allow easy printing of  Values from the debugger.
+// Located here because so much of the needed functionality is here.
+void Value::dump() const { print(*cerr.stream()); cerr << '\n'; }
+
+// Type::dump - allow easy printing of  Values from the debugger.
+// Located here because so much of the needed functionality is here.
+void Type::dump() const { print(*cerr.stream()); cerr << '\n'; }
+
+void
+ParamAttrsList::dump() const {
+  cerr << "PAL[ ";
+  for (unsigned i = 0; i < attrs.size(); ++i) {
+    uint16_t index = getParamIndex(i);
+    uint16_t attrs = getParamAttrs(index);
+    cerr << "{" << index << "," << attrs << "} ";
+  }
+  cerr << "]\n";
+}
 
 //===----------------------------------------------------------------------===//
-//  CachedWriter Class Implementation
+//                         SlotMachine Implementation
 //===----------------------------------------------------------------------===//
 
-void CachedWriter::setModule(const Module *M) {
-  delete SC; delete AW;
-  if (M) {
-    SC = new SlotCalculator(M, true);
-    AW = new AssemblyWriter(Out, *SC, M);
-  } else {
-    SC = 0; AW = 0;
+#if 0
+#define SC_DEBUG(X) cerr << X
+#else
+#define SC_DEBUG(X)
+#endif
+
+// Module level constructor. Causes the contents of the Module (sans functions)
+// to be added to the slot table.
+SlotMachine::SlotMachine(const Module *M)
+  : TheModule(M)    ///< Saved for lazy initialization.
+  , TheFunction(0)
+  , FunctionProcessed(false)
+  , mMap(), mNext(0), fMap(), fNext(0)
+{
+}
+
+// Function level constructor. Causes the contents of the Module and the one
+// function provided to be added to the slot table.
+SlotMachine::SlotMachine(const Function *F)
+  : TheModule(F ? F->getParent() : 0) ///< Saved for lazy initialization
+  , TheFunction(F) ///< Saved for lazy initialization
+  , FunctionProcessed(false)
+  , mMap(), mNext(0), fMap(), fNext(0)
+{
+}
+
+inline void SlotMachine::initialize() {
+  if (TheModule) {
+    processModule();
+    TheModule = 0; ///< Prevent re-processing next time we're called.
   }
+  if (TheFunction && !FunctionProcessed)
+    processFunction();
 }
 
-CachedWriter::~CachedWriter() {
-  delete AW;
-  delete SC;
+// Iterate through all the global variables, functions, and global
+// variable initializers and create slots for them.
+void SlotMachine::processModule() {
+  SC_DEBUG("begin processModule!\n");
+
+  // Add all of the unnamed global variables to the value table.
+  for (Module::const_global_iterator I = TheModule->global_begin(),
+       E = TheModule->global_end(); I != E; ++I)
+    if (!I->hasName()) 
+      CreateModuleSlot(I);
+
+  // Add all the unnamed functions to the table.
+  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
+       I != E; ++I)
+    if (!I->hasName())
+      CreateModuleSlot(I);
+
+  SC_DEBUG("end processModule!\n");
 }
 
-CachedWriter &CachedWriter::operator<<(const Value *V) {
-  assert(AW && SC && "CachedWriter does not have a current module!");
-  switch (V->getValueType()) {
-  case Value::ConstantVal:
-  case Value::ArgumentVal:       AW->writeOperand(V, true, true); break;
-  case Value::TypeVal:           AW->write(cast<Type>(V)); break;
-  case Value::InstructionVal:    AW->write(cast<Instruction>(V)); break;
-  case Value::BasicBlockVal:     AW->write(cast<BasicBlock>(V)); break;
-  case Value::FunctionVal:       AW->write(cast<Function>(V)); break;
-  case Value::GlobalVariableVal: AW->write(cast<GlobalVariable>(V)); break;
-  default: Out << "<unknown value type: " << V->getValueType() << ">"; break;
+
+// Process the arguments, basic blocks, and instructions  of a function.
+void SlotMachine::processFunction() {
+  SC_DEBUG("begin processFunction!\n");
+  fNext = 0;
+
+  // Add all the function arguments with no names.
+  for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
+      AE = TheFunction->arg_end(); AI != AE; ++AI)
+    if (!AI->hasName())
+      CreateFunctionSlot(AI);
+
+  SC_DEBUG("Inserting Instructions:\n");
+
+  // Add all of the basic blocks and instructions with no names.
+  for (Function::const_iterator BB = TheFunction->begin(),
+       E = TheFunction->end(); BB != E; ++BB) {
+    if (!BB->hasName())
+      CreateFunctionSlot(BB);
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
+      if (I->getType() != Type::VoidTy && !I->hasName())
+        CreateFunctionSlot(I);
   }
-  return *this;
+
+  FunctionProcessed = true;
+
+  SC_DEBUG("end processFunction!\n");
 }
+
+/// Clean up after incorporating a function. This is the only way to get out of
+/// the function incorporation state that affects get*Slot/Create*Slot. Function
+/// incorporation state is indicated by TheFunction != 0.
+void SlotMachine::purgeFunction() {
+  SC_DEBUG("begin purgeFunction!\n");
+  fMap.clear(); // Simply discard the function level map
+  TheFunction = 0;
+  FunctionProcessed = false;
+  SC_DEBUG("end purgeFunction!\n");
+}
+
+/// getGlobalSlot - Get the slot number of a global value.
+int SlotMachine::getGlobalSlot(const GlobalValue *V) {
+  // Check for uninitialized state and do lazy initialization.
+  initialize();
+  
+  // Find the type plane in the module map
+  ValueMap::const_iterator MI = mMap.find(V);
+  if (MI == mMap.end()) return -1;
+
+  return MI->second;
+}
+
+
+/// getLocalSlot - Get the slot number for a value that is local to a function.
+int SlotMachine::getLocalSlot(const Value *V) {
+  assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!");
+
+  // Check for uninitialized state and do lazy initialization.
+  initialize();
+
+  ValueMap::const_iterator FI = fMap.find(V);
+  if (FI == fMap.end()) return -1;
+  
+  return FI->second;
+}
+
+
+/// CreateModuleSlot - Insert the specified GlobalValue* into the slot table.
+void SlotMachine::CreateModuleSlot(const GlobalValue *V) {
+  assert(V && "Can't insert a null Value into SlotMachine!");
+  assert(V->getType() != Type::VoidTy && "Doesn't need a slot!");
+  assert(!V->hasName() && "Doesn't need a slot!");
+  
+  unsigned DestSlot = mNext++;
+  mMap[V] = DestSlot;
+  
+  SC_DEBUG("  Inserting value [" << V->getType() << "] = " << V << " slot=" <<
+           DestSlot << " [");
+  // G = Global, F = Function, A = Alias, o = other
+  SC_DEBUG((isa<GlobalVariable>(V) ? 'G' :
+            (isa<Function> ? 'F' :
+             (isa<GlobalAlias> ? 'A' : 'o'))) << "]\n");
+}
+
+
+/// CreateSlot - Create a new slot for the specified value if it has no name.
+void SlotMachine::CreateFunctionSlot(const Value *V) {
+  const Type *VTy = V->getType();
+  assert(VTy != Type::VoidTy && !V->hasName() && "Doesn't need a slot!");
+  
+  unsigned DestSlot = fNext++;
+  fMap[V] = DestSlot;
+  
+  // G = Global, F = Function, o = other
+  SC_DEBUG("  Inserting value [" << VTy << "] = " << V << " slot=" <<
+           DestSlot << " [o]\n");
+}