For PR411:
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index 317eb8e0aac38e8a539a3cdbf36d03950994d8e5..e834c53db3fbdbcb1ba621a575bf3c4a54f5949b 100644 (file)
@@ -24,7 +24,8 @@
 #include "llvm/Instruction.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.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"
@@ -74,9 +75,9 @@ public:
 /// @{
 public:
   /// Return the slot number of the specified value in it's type
-  /// plane.  Its an error to ask for something not in the SlotMachine.
-  /// Its an error to ask for a Type*
-  int getSlot(const Value *V);
+  /// plane.  If something is not in the SlotMachine, return -1.
+  int getLocalSlot(const Value *V);
+  int getGlobalSlot(const GlobalValue *V);
 
 /// @}
 /// @name Mutators
@@ -101,15 +102,11 @@ private:
   /// This function does the actual initialization.
   inline void initialize();
 
-  /// Values can be crammed into here at will. If they haven't
-  /// been inserted already, they get inserted, otherwise they are ignored.
-  /// Either way, the slot number for the Value* is returned.
-  unsigned getOrCreateSlot(const Value *V);
-
-  /// Insert a value into the value table. Return the slot number
-  /// that it now occupies.  BadThings(TM) will happen if you insert a
-  /// Value that's already been inserted.
-  unsigned insertValue(const Value *V);
+  /// 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.
@@ -182,31 +179,47 @@ static SlotMachine *createSlotMachine(const Value *V) {
   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,
-                               bool prefixName = true) {
-  assert(!Name.empty() && "Cannot get empty name!");
-
-  // First character cannot start with a number...
-  if (Name[0] >= '0' && Name[0] <= '9')
-    return "\"" + Name + "\"";
-
+/// NameNeedsQuotes - Return true if the specified llvm name should be wrapped
+/// with ""'s.
+static bool NameNeedsQuotes(const std::string &Name) {
+  if (Name[0] >= '0' && Name[0] <= '9') return true;
   // Scan to see if we have any characters that are not on the "white list"
   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 + "\"";
+      return true;
+  }
+  return false;
+}
+
+enum PrefixType {
+  GlobalPrefix,
+  LabelPrefix,
+  LocalPrefix
+};
+
+/// 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!");
+
+  // First character cannot start with a number...
+  if (NameNeedsQuotes(Name)) {
+    if (Prefix == GlobalPrefix)
+      return "@\"" + Name + "\"";
+    return "\"" + Name + "\"";
   }
 
   // If we get here, then the identifier is legal to use as a "VarID".
-  if (prefixName)
-    return "%"+Name;
-  else
-    return Name;
+  switch (Prefix) {
+  default: assert(0 && "Bad prefix!");
+  case GlobalPrefix: return '@' + Name;
+  case LabelPrefix:  return Name;
+  case LocalPrefix:  return '%' + Name;
+  }      
 }
 
 
@@ -216,17 +229,18 @@ static std::string getLLVMName(const std::string &Name,
 static void fillTypeNameTable(const Module *M,
                               std::map<const Type *, std::string> &TypeNames) {
   if (!M) return;
-  const SymbolTable &ST = M->getSymbolTable();
-  SymbolTable::type_const_iterator TI = ST.type_begin();
-  for (; TI != ST.type_end(); ++TI) {
+  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)));
+      TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first, LocalPrefix)));
   }
 }
 
@@ -236,7 +250,7 @@ static void calcTypeName(const Type *Ty,
                          std::vector<const Type *> &TypeStack,
                          std::map<const Type *, std::string> &TypeNames,
                          std::string & Result){
-  if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)) {
+  if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))) {
     Result += Ty->getDescription();  // Base case
     return;
   }
@@ -268,13 +282,14 @@ static void calcTypeName(const Type *Ty,
   TypeStack.push_back(Ty);    // Recursive case: Add us to the stack..
 
   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);
     calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result);
-    if (FTy->getParamAttrs(0)) {
-      Result += " ";
-      Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
-    }
     Result += " (";
     unsigned Idx = 1;
     for (FunctionType::param_iterator I = FTy->param_begin(),
@@ -293,6 +308,10 @@ static void calcTypeName(const Type *Ty,
       Result += "...";
     }
     Result += ")";
+    if (FTy->getParamAttrs(0)) {
+      Result += " ";
+      Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
+    }
     break;
   }
   case Type::StructTyID: {
@@ -350,7 +369,7 @@ static std::ostream &printTypeInt(std::ostream &Out, const Type *Ty,
   // Primitive types always print out their description, regardless of whether
   // they have been named or not.
   //
-  if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))
+  if (Ty->isInteger() || (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)))
     return Out << Ty->getDescription();
 
   // Check to see if the type is named.
@@ -441,10 +460,11 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
                              SlotMachine *Machine) {
   const int IndentSize = 4;
   static std::string Indent = "\n";
-  if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
-    Out << (CB->getValue() ? "true" : "false");
-  } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
-    Out << CI->getSExtValue();
+  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+    if (CI->getType() == Type::Int1Ty) 
+      Out << (CI->getZExtValue() ? "true" : "false");
+    else 
+      Out << CI->getSExtValue();
   } 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
@@ -500,6 +520,8 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
       Out << " ]";
     }
   } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
+    if (CS->getType()->isPacked())
+      Out << '<';
     Out << '{';
     unsigned N = CS->getNumOperands();
     if (N) {
@@ -524,6 +546,8 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
     }
  
     Out << " }";
+    if (CS->getType()->isPacked())
+      Out << '>';
   } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
       const Type *ETy = CP->getType()->getElementType();
       assert(CP->getNumOperands() > 0 &&
@@ -579,7 +603,8 @@ static void WriteAsOperandInternal(std::ostream &Out, const Value *V,
                                    SlotMachine *Machine) {
   Out << ' ';
   if (V->hasName())
-    Out << getLLVMName(V->getName());
+    Out << getLLVMName(V->getName(),
+                       isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);
   else {
     const Constant *CV = dyn_cast<Constant>(V);
     if (CV && !isa<GlobalValue>(CV)) {
@@ -594,19 +619,31 @@ static void WriteAsOperandInternal(std::ostream &Out, const Value *V,
       PrintEscapedString(IA->getConstraintString(), Out);
       Out << '"';
     } else {
+      char Prefix = '%';
       int Slot;
       if (Machine) {
-        Slot = Machine->getSlot(V);
+        if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+          Slot = Machine->getGlobalSlot(GV);
+          Prefix = '@';
+        } else {
+          Slot = Machine->getLocalSlot(V);
+        }
       } else {
         Machine = createSlotMachine(V);
-        if (Machine)
-          Slot = Machine->getSlot(V);
-        else
+        if (Machine) {
+          if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+            Slot = Machine->getGlobalSlot(GV);
+            Prefix = '@';
+          } else {
+            Slot = Machine->getLocalSlot(V);
+          }
+        } else {
           Slot = -1;
+        }
         delete Machine;
       }
       if (Slot != -1)
-        Out << '%' << Slot;
+        Out << Prefix << Slot;
       else
         Out << "<badref>";
     }
@@ -657,7 +694,6 @@ public:
   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);       }
 
   void writeOperand(const Value *Op, bool PrintType);
@@ -666,8 +702,7 @@ public:
 
 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 printFunction(const Function *F);
   void printArgument(const Argument *FA, FunctionType::ParameterAttributes A);
@@ -696,10 +731,10 @@ private:
 /// 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)) {
+  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());
-    if (FTy->getParamAttrs(0))
-      Out << ' ' << FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
     Out << " (";
     unsigned Idx = 1;
     for (FunctionType::param_iterator I = FTy->param_begin(),
@@ -717,6 +752,8 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
       Out << "...";
     }
     Out << ')';
+    if (FTy->getParamAttrs(0))
+      Out << ' ' << FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
   } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
     if (STy->isPacked())
       Out << '<';
@@ -769,17 +806,6 @@ void AssemblyWriter::printModule(const Module *M) {
 
   if (!M->getDataLayout().empty())
     Out << "target datalayout = \"" << M->getDataLayout() << "\"\n";
-
-  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->getTargetTriple().empty())
     Out << "target triple = \"" << M->getTargetTriple() << "\"\n";
 
@@ -818,7 +844,7 @@ void AssemblyWriter::printModule(const Module *M) {
   }
 
   // Loop over the symbol table, emitting all named constants.
-  printSymbolTable(M->getSymbolTable());
+  printTypeSymbolTable(M->getTypeSymbolTable());
 
   for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
        I != E; ++I)
@@ -832,15 +858,14 @@ void AssemblyWriter::printModule(const Module *M) {
 }
 
 void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
-  if (GV->hasName()) Out << getLLVMName(GV->getName()) << " = ";
+  if (GV->hasName()) Out << getLLVMName(GV->getName(), GlobalPrefix) << " = ";
 
   if (!GV->hasInitializer())
     switch (GV->getLinkage()) {
      case GlobalValue::DLLImportLinkage:   Out << "dllimport "; break;
      case GlobalValue::ExternalWeakLinkage: Out << "extern_weak "; break;
      default: Out << "external "; break;
-    }
-  else
+    } else {
     switch (GV->getLinkage()) {
     case GlobalValue::InternalLinkage:     Out << "internal "; break;
     case GlobalValue::LinkOnceLinkage:     Out << "linkonce "; break;
@@ -854,7 +879,13 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
       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;
+    }
+  }
+  
   Out << (GV->isConstant() ? "constant " : "global ");
   printType(GV->getType()->getElementType());
 
@@ -873,53 +904,17 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
   Out << "\n";
 }
 
-
-// printSymbolTable - Run through symbol table looking for constants
-// and types. Emit their declarations.
-void AssemblyWriter::printSymbolTable(const SymbolTable &ST) {
-
+void AssemblyWriter::printTypeSymbolTable(const TypeSymbolTable &ST) {
   // Print the types.
-  for (SymbolTable::type_const_iterator TI = ST.type_begin();
-       TI != ST.type_end(); ++TI) {
-    Out << "\t" << getLLVMName(TI->first) << " = type ";
+  for (TypeSymbolTable::const_iterator TI = ST.begin(), TE = ST.end();
+       TI != TE; ++TI) {
+    Out << "\t" << getLLVMName(TI->first, LocalPrefix) << " = type ";
 
     // 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";
   }
-
-  // Print the constants, in type plane order.
-  for (SymbolTable::plane_const_iterator PI = ST.plane_begin();
-       PI != ST.plane_end(); ++PI) {
-    SymbolTable::value_const_iterator VI = ST.value_begin(PI->first);
-    SymbolTable::value_const_iterator VE = ST.value_end(PI->first);
-
-    for (; VI != VE; ++VI) {
-      const Value* V = VI->second;
-      const Constant *CPV = dyn_cast<Constant>(V) ;
-      if (CPV && !isa<GlobalValue>(V)) {
-        printConstant(CPV);
-      }
-    }
-  }
-}
-
-
-/// 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);
-
-  printInfoComment(*CPV);
-  Out << "\n";
 }
 
 /// printFunction - Print all aspects of a function.
@@ -928,12 +923,9 @@ void AssemblyWriter::printFunction(const Function *F) {
   // Print out the return type and name...
   Out << "\n";
 
-  // Ensure that no local symbols conflict with global symbols.
-  const_cast<Function*>(F)->renameLocalSymbols();
-
   if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
 
-  if (F->isExternal())
+  if (F->isDeclaration())
     switch (F->getLinkage()) {
     case GlobalValue::DLLImportLinkage:    Out << "declare dllimport "; break;
     case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
@@ -954,12 +946,16 @@ void AssemblyWriter::printFunction(const Function *F) {
       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;
+    }
   }
 
   // Print the calling convention.
   switch (F->getCallingConv()) {
   case CallingConv::C: break;   // default
-  case CallingConv::CSRet:        Out << "csretcc "; break;
   case CallingConv::Fast:         Out << "fastcc "; break;
   case CallingConv::Cold:         Out << "coldcc "; break;
   case CallingConv::X86_StdCall:  Out << "x86_stdcallcc "; break;
@@ -969,12 +965,10 @@ void AssemblyWriter::printFunction(const Function *F) {
 
   const FunctionType *FT = F->getFunctionType();
   printType(F->getReturnType()) << ' ';
-  if (FT->getParamAttrs(0))
-    Out << FunctionType::getParamAttrsText(FT->getParamAttrs(0)) << ' ';
   if (!F->getName().empty())
-    Out << getLLVMName(F->getName());
+    Out << getLLVMName(F->getName(), GlobalPrefix);
   else
-    Out << "\"\"";
+    Out << "@\"\"";
   Out << '(';
   Machine.incorporateFunction(F);
 
@@ -995,13 +989,14 @@ void AssemblyWriter::printFunction(const Function *F) {
     Out << "...";  // Output varargs portion of signature!
   }
   Out << ')';
-
+  if (FT->getParamAttrs(0))
+    Out << ' ' << FunctionType::getParamAttrsText(FT->getParamAttrs(0));
   if (F->hasSection())
     Out << " section \"" << F->getSection() << '"';
   if (F->getAlignment())
     Out << " align " << F->getAlignment();
 
-  if (F->isExternal()) {
+  if (F->isDeclaration()) {
     Out << "\n";
   } else {
     Out << " {";
@@ -1029,17 +1024,17 @@ void AssemblyWriter::printArgument(const Argument *Arg,
 
   // Output name, if available...
   if (Arg->hasName())
-    Out << ' ' << getLLVMName(Arg->getName());
+    Out << ' ' << getLLVMName(Arg->getName(), LocalPrefix);
 }
 
 /// 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" << getLLVMName(BB->getName(), false) << ':';
+    Out << "\n" << getLLVMName(BB->getName(), LabelPrefix) << ':';
   } else if (!BB->use_empty()) {      // Don't print block # of no uses...
     Out << "\n; <label>:";
-    int Slot = Machine.getSlot(BB);
+    int Slot = Machine.getLocalSlot(BB);
     if (Slot != -1)
       Out << Slot;
     else
@@ -1088,7 +1083,11 @@ void AssemblyWriter::printInfoComment(const Value &V) {
     printType(V.getType()) << '>';
 
     if (!V.hasName()) {
-      int SlotNum = Machine.getSlot(&V);
+      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
@@ -1106,7 +1105,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
 
   // 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()) ||
@@ -1166,7 +1165,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     // Print the calling convention being used.
     switch (CI->getCallingConv()) {
     case CallingConv::C: break;   // default
-    case CallingConv::CSRet: Out << " csretcc"; break;
     case CallingConv::Fast:  Out << " fastcc"; break;
     case CallingConv::Cold:  Out << " coldcc"; break;
     case CallingConv::X86_StdCall:  Out << "x86_stdcallcc "; break;
@@ -1186,8 +1184,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
         (!isa<PointerType>(RetTy) ||
          !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
       Out << ' '; printType(RetTy);
-      if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
-        Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0));
       writeOperand(Operand, false);
     } else {
       writeOperand(Operand, true);
@@ -1201,6 +1197,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
         Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op));
     }
     Out << " )";
+    if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
+      Out << ' ' << FTy->getParamAttrsText(FTy->getParamAttrs(0));
   } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
     const PointerType  *PTy = cast<PointerType>(Operand->getType());
     const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
@@ -1209,7 +1207,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     // Print the calling convention being used.
     switch (II->getCallingConv()) {
     case CallingConv::C: break;   // default
-    case CallingConv::CSRet: Out << " csretcc"; break;
     case CallingConv::Fast:  Out << " fastcc"; break;
     case CallingConv::Cold:  Out << " coldcc"; break;
     case CallingConv::X86_StdCall:  Out << "x86_stdcallcc "; break;
@@ -1225,8 +1222,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
         (!isa<PointerType>(RetTy) ||
          !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
       Out << ' '; printType(RetTy);
-      if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
-        Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0));
       writeOperand(Operand, false);
     } else {
       writeOperand(Operand, true);
@@ -1237,11 +1232,14 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
       if (op > 3)
         Out << ',';
       writeOperand(I.getOperand(op), true);
-      if (FTy->getParamAttrs(op) != FunctionType::NoAttributeSet)
-        Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op));
+      if (FTy->getParamAttrs(op-2) != FunctionType::NoAttributeSet)
+        Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op-2));
     }
 
-    Out << " )\n\t\t\tto";
+    Out << " )";
+    if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
+      Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0));
+    Out << "\n\t\t\tto";
     writeOperand(II->getNormalDest(), true);
     Out << " unwind";
     writeOperand(II->getUnwindDest(), true);
@@ -1272,10 +1270,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     bool PrintAllTypes = false;
     const Type *TheType = Operand->getType();
 
-    // Shift Left & Right print both types even for Ubyte LHS, and select prints
-    // types even if all operands are bools.
-    if (isa<ShiftInst>(I) || isa<SelectInst>(I) || isa<StoreInst>(I) ||
-        isa<ShuffleVectorInst>(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) {
@@ -1401,7 +1397,7 @@ SlotMachine::SlotMachine(const Function *F)
 {
 }
 
-inline void SlotMachine::initialize(void) {
+inline void SlotMachine::initialize() {
   if (TheModule) {
     processModule();
     TheModule = 0; ///< Prevent re-processing next time we're called.
@@ -1419,13 +1415,13 @@ void SlotMachine::processModule() {
   for (Module::const_global_iterator I = TheModule->global_begin(),
        E = TheModule->global_end(); I != E; ++I)
     if (!I->hasName()) 
-      getOrCreateSlot(I);
+      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())
-      getOrCreateSlot(I);
+      CreateModuleSlot(I);
 
   SC_DEBUG("end processModule!\n");
 }
@@ -1439,7 +1435,7 @@ void SlotMachine::processFunction() {
   for(Function::const_arg_iterator AI = TheFunction->arg_begin(),
       AE = TheFunction->arg_end(); AI != AE; ++AI)
     if (!AI->hasName())
-      getOrCreateSlot(AI);
+      CreateFunctionSlot(AI);
 
   SC_DEBUG("Inserting Instructions:\n");
 
@@ -1447,10 +1443,10 @@ void SlotMachine::processFunction() {
   for (Function::const_iterator BB = TheFunction->begin(),
        E = TheFunction->end(); BB != E; ++BB) {
     if (!BB->hasName())
-      getOrCreateSlot(BB);
+      CreateFunctionSlot(BB);
     for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
       if (I->getType() != Type::VoidTy && !I->hasName())
-        getOrCreateSlot(I);
+        CreateFunctionSlot(I);
   }
 
   FunctionProcessed = true;
@@ -1459,9 +1455,8 @@ void SlotMachine::processFunction() {
 }
 
 /// Clean up after incorporating a function. This is the only way to get out of
-/// the function incorporation state that affects the
-/// getSlot/getOrCreateSlot lock. Function incorporation state is indicated
-/// by TheFunction != 0.
+/// 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
@@ -1470,173 +1465,72 @@ void SlotMachine::purgeFunction() {
   SC_DEBUG("end purgeFunction!\n");
 }
 
-/// Get the slot number for a value. This function will assert if you
-/// ask for a Value that hasn't previously been inserted with getOrCreateSlot.
-/// Types are forbidden because Type does not inherit from Value (any more).
-int SlotMachine::getSlot(const Value *V) {
-  assert(V && "Can't get slot for null Value");
-  assert(!isa<Constant>(V) || isa<GlobalValue>(V) &&
-    "Can't insert a non-GlobalValue Constant into SlotMachine");
-
-  // Check for uninitialized state and do lazy initialization
-  this->initialize();
-
-  // Get the type of the value
-  const Type* VTy = V->getType();
-
+/// 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
-  TypedPlanes::const_iterator MI = mMap.find(VTy);
-
-  if (TheFunction) {
-    // Lookup the type in the function map too
-    TypedPlanes::const_iterator FI = fMap.find(VTy);
-    // If there is a corresponding type plane in the function map
-    if (FI != fMap.end()) {
-      // Lookup the Value in the function map
-      ValueMap::const_iterator FVI = FI->second.map.find(V);
-      // If the value doesn't exist in the function map
-      if (FVI == FI->second.map.end()) {
-        // Look up the value in the module map.
-        if (MI == mMap.end()) return -1;
-        ValueMap::const_iterator MVI = MI->second.map.find(V);
-        // If we didn't find it, it wasn't inserted
-        if (MVI == MI->second.map.end()) return -1;
-        assert(MVI != MI->second.map.end() && "Value not found");
-        // We found it only at the module level
-        return MVI->second;
-
-      // else the value exists in the function map
-      } else {
-        // Return the slot number as the module's contribution to
-        // the type plane plus the index in the function's contribution
-        // to the type plane.
-        if (MI != mMap.end())
-          return MI->second.next_slot + FVI->second;
-        else
-          return FVI->second;
-      }
-    }
-  }
-
-  // N.B. Can get here only if either !TheFunction or the function doesn't
-  // have a corresponding type plane for the Value
-
-  // Make sure the type plane exists
+  TypedPlanes::const_iterator MI = mMap.find(V->getType());
   if (MI == mMap.end()) return -1;
-  // Lookup the value in the module's map
+  
+  // Lookup the value in the module plane's map.
   ValueMap::const_iterator MVI = MI->second.map.find(V);
-  // Make sure we found it.
-  if (MVI == MI->second.map.end()) return -1;
-  // Return it.
-  return MVI->second;
+  return MVI != MI->second.map.end() ? int(MVI->second) : -1;
 }
 
 
-// Create a new slot, or return the existing slot if it is already
-// inserted. Note that the logic here parallels getSlot but instead
-// of asserting when the Value* isn't found, it inserts the value.
-unsigned SlotMachine::getOrCreateSlot(const Value *V) {
-  const Type* VTy = V->getType();
-  assert(VTy != Type::VoidTy && !V->hasName() && "Doesn't need a slot!");
-  assert(!isa<Constant>(V) || isa<GlobalValue>(V) &&
-    "Can't insert a non-GlobalValue Constant into SlotMachine");
-
-  // Look up the type plane for the Value's type from the module map
-  TypedPlanes::const_iterator MI = mMap.find(VTy);
-
-  if (TheFunction) {
-    // Get the type plane for the Value's type from the function map
-    TypedPlanes::const_iterator FI = fMap.find(VTy);
-    // If there is a corresponding type plane in the function map
-    if (FI != fMap.end()) {
-      // Lookup the Value in the function map
-      ValueMap::const_iterator FVI = FI->second.map.find(V);
-      // If the value doesn't exist in the function map
-      if (FVI == FI->second.map.end()) {
-        // If there is no corresponding type plane in the module map
-        if (MI == mMap.end())
-          return insertValue(V);
-        // Look up the value in the module map
-        ValueMap::const_iterator MVI = MI->second.map.find(V);
-        // If we didn't find it, it wasn't inserted
-        if (MVI == MI->second.map.end())
-          return insertValue(V);
-        else
-          // We found it only at the module level
-          return MVI->second;
-
-      // else the value exists in the function map
-      } else {
-        if (MI == mMap.end())
-          return FVI->second;
-        else
-          // Return the slot number as the module's contribution to
-          // the type plane plus the index in the function's contribution
-          // to the type plane.
-          return MI->second.next_slot + FVI->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!");
 
-    // else there is not a corresponding type plane in the function map
-    } else {
-      // If the type plane doesn't exists at the module level
-      if (MI == mMap.end()) {
-        return insertValue(V);
-      // else type plane exists at the module level, examine it
-      } else {
-        // Look up the value in the module's map
-        ValueMap::const_iterator MVI = MI->second.map.find(V);
-        // If we didn't find it there either
-        if (MVI == MI->second.map.end())
-          // Return the slot number as the module's contribution to
-          // the type plane plus the index of the function map insertion.
-          return MI->second.next_slot + insertValue(V);
-        else
-          return MVI->second;
-      }
-    }
-  }
-
-  // N.B. Can only get here if TheFunction == 0
+  // Check for uninitialized state and do lazy initialization.
+  initialize();
 
-  // If the module map's type plane is not for the Value's type
-  if (MI != mMap.end()) {
-    // Lookup the value in the module's map
-    ValueMap::const_iterator MVI = MI->second.map.find(V);
-    if (MVI != MI->second.map.end())
-      return MVI->second;
-  }
+  // Get the type of the value
+  const Type *VTy = V->getType();
 
-  return insertValue(V);
+  TypedPlanes::const_iterator FI = fMap.find(VTy);
+  if (FI == fMap.end()) return -1;
+  
+  // Lookup the Value in the function and module maps.
+  ValueMap::const_iterator FVI = FI->second.map.find(V);
+  
+  // If the value doesn't exist in the function map, it is a <badref>
+  if (FVI == FI->second.map.end()) return -1;
+  
+  return FVI->second;
 }
 
 
-// Low level insert function. Minimal checking is done. This
-// function is just for the convenience of getOrCreateSlot (above).
-unsigned SlotMachine::insertValue(const Value *V) {
+/// 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(!isa<Constant>(V) || isa<GlobalValue>(V) &&
-         "Can't insert a non-GlobalValue Constant into SlotMachine");
-  assert(V->getType() != Type::VoidTy && !V->hasName());
-
-  const Type *VTy = V->getType();
+  
   unsigned DestSlot = 0;
-
-  if (TheFunction) {
-    TypedPlanes::iterator I = fMap.find(VTy);
-    if (I == fMap.end())
-      I = fMap.insert(std::make_pair(VTy,ValuePlane())).first;
-    DestSlot = I->second.map[V] = I->second.next_slot++;
-  } else {
-    TypedPlanes::iterator I = mMap.find(VTy);
-    if (I == mMap.end())
-      I = mMap.insert(std::make_pair(VTy,ValuePlane())).first;
-    DestSlot = I->second.map[V] = I->second.next_slot++;
-  }
-
+  const Type *VTy = V->getType();
+  
+  ValuePlane &PlaneMap = mMap[VTy];
+  DestSlot = PlaneMap.map[V] = PlaneMap.next_slot++;
+  
   SC_DEBUG("  Inserting value [" << VTy << "] = " << V << " slot=" <<
            DestSlot << " [");
   // G = Global, F = Function, o = other
-  SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : (isa<Function>(V) ? 'F' : 'o')));
-  SC_DEBUG("]\n");
-  return DestSlot;
+  SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : 'F') << "]\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 = 0;
+  
+  ValuePlane &PlaneMap = fMap[VTy];
+  DestSlot = PlaneMap.map[V] = PlaneMap.next_slot++;
+  
+  // G = Global, F = Function, o = other
+  SC_DEBUG("  Inserting value [" << VTy << "] = " << V << " slot=" <<
+           DestSlot << " [o]\n");
+}