Adding a collector name attribute to Function in the IR. These
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index f5b24844295ae6419c07bd3eb1da4d7b6f85dfda..008c1daee192b91d53d246ec4eb81d146289872b 100644 (file)
 #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/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 "llvm/Support/MathExtras.h"
 #include "llvm/Support/Streams.h"
 #include <algorithm>
+#include <cctype>
 using namespace llvm;
 
 namespace llvm {
@@ -47,17 +50,7 @@ class SlotMachine {
 public:
 
   /// @brief A mapping of Values to slot numbers
-  typedef std::map<const Value*, unsigned> ValueMap;
-
-  /// @brief A plane with next slot number and ValueMap
-  struct ValuePlane {
-    unsigned next_slot;        ///< The next slot number to use
-    ValueMap map;              ///< The map of Value* -> unsigned
-    ValuePlane() { next_slot = 0; } ///< Make sure we start at 0
-  };
-
-  /// @brief The map of planes by Type
-  typedef std::map<const Type*, ValuePlane> TypedPlanes;
+  typedef std::map<const Value*,unsigned> ValueMap;
 
 /// @}
 /// @name Constructors
@@ -74,9 +67,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 +94,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.
@@ -134,10 +123,12 @@ public:
   bool FunctionProcessed;
 
   /// @brief The TypePlanes map for the module level data
-  TypedPlanes mMap;
+  ValueMap mMap;
+  unsigned mNext;
 
   /// @brief The TypePlanes map for the function level data
-  TypedPlanes fMap;
+  ValueMap fMap;
+  unsigned fNext;
 
 /// @}
 
@@ -145,8 +136,10 @@ public:
 
 }  // end namespace llvm
 
+char PrintModulePass::ID = 0;
 static RegisterPass<PrintModulePass>
 X("printm", "Print module to stderr");
+char PrintFunctionPass::ID = 0;
 static RegisterPass<PrintFunctionPass>
 Y("print","Print function to stderr");
 
@@ -176,37 +169,71 @@ static SlotMachine *createSlotMachine(const Value *V) {
     return new SlotMachine(BB->getParent());
   } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)){
     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 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,
-                               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 + "\"";
-
-  // 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 (needsQuotes) {
+    result.insert(0,"\"");
+    result += '"';
+  }
+  return result;
+}
 
-  // If we get here, then the identifier is legal to use as a "VarID".
-  if (prefixName)
-    return "%"+Name;
-  else
-    return Name;
+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!");
+  switch (Prefix) {
+  default: assert(0 && "Bad prefix!");
+  case GlobalPrefix: return '@' + QuoteNameIfNeeded(Name);
+  case LabelPrefix:  return QuoteNameIfNeeded(Name);
+  case LocalPrefix:  return '%' + QuoteNameIfNeeded(Name);
+  }      
 }
 
 
@@ -216,17 +243,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 +264,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,31 +296,26 @@ 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);
     Result += " (";
-    unsigned Idx = 1;
     for (FunctionType::param_iterator I = FTy->param_begin(),
-           E = FTy->param_end(); I != E; ++I) {
+         E = FTy->param_end(); I != E; ++I) {
       if (I != FTy->param_begin())
         Result += ", ";
       calcTypeName(*I, TypeStack, TypeNames, Result);
-      if (FTy->getParamAttrs(Idx)) {
-        Result += + " ";
-        Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(Idx));
-      }
-      Idx++;
     }
     if (FTy->isVarArg()) {
       if (FTy->getNumParams()) Result += ", ";
       Result += "...";
     }
     Result += ")";
-    if (FTy->getParamAttrs(0)) {
-      Result += " ";
-      Result += FunctionType::getParamAttrsText(FTy->getParamAttrs(0));
-    }
     break;
   }
   case Type::StructTyID: {
@@ -323,8 +346,8 @@ static void calcTypeName(const Type *Ty,
     Result += "]";
     break;
   }
-  case Type::PackedTyID: {
-    const PackedType *PTy = cast<PackedType>(Ty);
+  case Type::VectorTyID: {
+    const VectorType *PTy = cast<VectorType>(Ty);
     Result += "<" + utostr(PTy->getNumElements()) + " x ";
     calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result);
     Result += ">";
@@ -350,7 +373,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,37 +464,74 @@ 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->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(CFP->getValue()));
-
+      // 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;
+        }
+      }
+    }
   } else if (isa<ConstantAggregateZero>(CV)) {
     Out << "zeroinitializer";
   } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
@@ -500,6 +560,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,7 +586,9 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
     }
  
     Out << " }";
-  } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
+    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");
@@ -579,7 +643,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 +659,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>";
     }
@@ -652,25 +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);
+  void writeParamOperand(const Value *Operand, uint16_t Attrs);
 
   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, FunctionType::ParameterAttributes A);
+  void printArgument(const Argument *FA, uint16_t ParamAttrs);
   void printBasicBlock(const BasicBlock *BB);
   void printInstruction(const Instruction &I);
 
@@ -696,27 +774,22 @@ 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());
     Out << " (";
-    unsigned Idx = 1;
     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->getParamAttrs(Idx)) {
-        Out << " " << FunctionType::getParamAttrsText(FTy->getParamAttrs(Idx));
-      }
-      Idx++;
     }
     if (FTy->isVarArg()) {
       if (FTy->getNumParams()) Out << ", ";
       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 << '<';
@@ -735,7 +808,7 @@ std::ostream &AssemblyWriter::printTypeAtLeastOneLevel(const Type *Ty) {
   } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
     Out << '[' << ATy->getNumElements() << " x ";
     printType(ATy->getElementType()) << ']';
-  } else if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
+  } else if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) {
     Out << '<' << PTy->getNumElements() << " x ";
     printType(PTy->getElementType()) << '>';
   }
@@ -759,6 +832,20 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
   }
 }
 
+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) {
   if (!M->getModuleIdentifier().empty() &&
@@ -769,17 +856,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,13 +894,17 @@ 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)
     printGlobal(I);
-
-  Out << "\nimplementation   ; Functions:\n";
+  
+  // 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)
@@ -832,15 +912,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 +933,15 @@ 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;
+    case GlobalValue::ProtectedVisibility: Out << "protected "; break;
+    }
+  }
 
+  if (GV->isThreadLocal()) Out << "thread_local ";
   Out << (GV->isConstant() ? "constant " : "global ");
   printType(GV->getType()->getElementType());
 
@@ -863,63 +950,72 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
     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 constants
-// and types. Emit their declarations.
-void AssemblyWriter::printSymbolTable(const SymbolTable &ST) {
+  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();
+    
+  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 (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,38 +1024,36 @@ 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())
-    switch (F->getLinkage()) {
-    case GlobalValue::DLLImportLinkage:    Out << "declare dllimport "; break;
-    case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
-    default: Out << "declare ";
-    }
-  else {
+  if (F->isDeclaration())
+    Out << "declare ";
+  else
     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->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;
   }
 
   // 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;
@@ -968,23 +1062,42 @@ void AssemblyWriter::printFunction(const Function *F) {
   }
 
   const FunctionType *FT = F->getFunctionType();
+  const ParamAttrsList *Attrs = F->getParamAttrs();
   printType(F->getReturnType()) << ' ';
   if (!F->getName().empty())
-    Out << getLLVMName(F->getName());
+    Out << getLLVMName(F->getName(), GlobalPrefix);
   else
-    Out << "\"\"";
+    Out << "@\"\"";
   Out << '(';
   Machine.incorporateFunction(F);
 
   // Loop over the arguments, printing them...
 
   unsigned Idx = 1;
-  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, FT->getParamAttrs(Idx));
-    Idx++;
+  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...
@@ -993,14 +1106,16 @@ void AssemblyWriter::printFunction(const Function *F) {
     Out << "...";  // Output varargs portion of signature!
   }
   Out << ')';
-  if (FT->getParamAttrs(0))
-    Out << ' ' << FunctionType::getParamAttrsText(FT->getParamAttrs(0));
+  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->isExternal()) {
+  if (F->isDeclaration()) {
     Out << "\n";
   } else {
     Out << " {";
@@ -1018,27 +1133,27 @@ void AssemblyWriter::printFunction(const Function *F) {
 /// printArgument - This member is called for every argument that is passed into
 /// the function.  Simply print it out
 ///
-void AssemblyWriter::printArgument(const Argument *Arg, 
-                                   FunctionType::ParameterAttributes attrs) {
+void AssemblyWriter::printArgument(const Argument *Arg, uint16_t Attrs) {
   // Output type...
   printType(Arg->getType());
 
-  if (attrs != FunctionType::NoAttributeSet)
-    Out << ' ' << FunctionType::getParamAttrsText(attrs);
+  // Output parameter attributes list
+  if (Attrs != ParamAttr::None)
+    Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs);
 
   // 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
@@ -1048,7 +1163,7 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
   if (BB->getParent() == 0)
     Out << "\t\t; Error: Block without parent!";
   else {
-    if (BB != &BB->getParent()->front()) {  // Not the entry block?
+    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);
@@ -1087,7 +1202,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
@@ -1105,7 +1224,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()) ||
@@ -1165,17 +1284,17 @@ 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;
-    case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; 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 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,
@@ -1193,22 +1312,20 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) {
       if (op > 1)
         Out << ',';
-      writeOperand(I.getOperand(op), true);
-      if (FTy->getParamAttrs(op) != FunctionType::NoAttributeSet)
-        Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op));
+      writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op) : 0);
     }
     Out << " )";
-    if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
-      Out << ' ' << FTy->getParamAttrsText(FTy->getParamAttrs(0));
+    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::CSRet: Out << " csretcc"; break;
     case CallingConv::Fast:  Out << " fastcc"; break;
     case CallingConv::Cold:  Out << " coldcc"; break;
     case CallingConv::X86_StdCall:  Out << "x86_stdcallcc "; break;
@@ -1233,14 +1350,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) {
       if (op > 3)
         Out << ',';
-      writeOperand(I.getOperand(op), true);
-      if (FTy->getParamAttrs(op-2) != FunctionType::NoAttributeSet)
-        Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(op-2));
+      writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op-2) : 0);
     }
 
     Out << " )";
-    if (FTy->getParamAttrs(0) != FunctionType::NoAttributeSet)
-      Out << " " << FTy->getParamAttrsText(FTy->getParamAttrs(0));
+    if (PAL && PAL->getParamAttrs(0) != ParamAttr::None)
+      Out << " " << PAL->getParamAttrsTextByIndex(0);
     Out << "\n\t\t\tto";
     writeOperand(II->getNormalDest(), true);
     Out << " unwind";
@@ -1272,10 +1387,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) {
@@ -1297,6 +1410,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
       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";
@@ -1319,6 +1439,12 @@ void GlobalVariable::print(std::ostream &o) const {
   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, AssemblyAnnotationWriter *AAW) const {
   SlotMachine SlotTable(getParent());
   AssemblyWriter W(o, SlotTable, getParent(), AAW);
@@ -1373,6 +1499,17 @@ void Value::dump() const { print(*cerr.stream()); cerr << '\n'; }
 // 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";
+}
+
 //===----------------------------------------------------------------------===//
 //                         SlotMachine Implementation
 //===----------------------------------------------------------------------===//
@@ -1389,6 +1526,7 @@ SlotMachine::SlotMachine(const Module *M)
   : TheModule(M)    ///< Saved for lazy initialization.
   , TheFunction(0)
   , FunctionProcessed(false)
+  , mMap(), mNext(0), fMap(), fNext(0)
 {
 }
 
@@ -1398,10 +1536,11 @@ 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(void) {
+inline void SlotMachine::initialize() {
   if (TheModule) {
     processModule();
     TheModule = 0; ///< Prevent re-processing next time we're called.
@@ -1419,13 +1558,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");
 }
@@ -1434,12 +1573,13 @@ void SlotMachine::processModule() {
 // 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())
-      getOrCreateSlot(AI);
+      CreateFunctionSlot(AI);
 
   SC_DEBUG("Inserting Instructions:\n");
 
@@ -1447,10 +1587,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 +1599,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 +1609,60 @@ 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
+  ValueMap::const_iterator MI = mMap.find(V);
   if (MI == mMap.end()) return -1;
-  // Lookup the value in the module'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;
-}
-
-
-// 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;
-      }
+  return MI->second;
+}
 
-    // 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
+/// 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!");
 
-  // 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;
-  }
+  // Check for uninitialized state and do lazy initialization.
+  initialize();
 
-  return insertValue(V);
+  ValueMap::const_iterator FI = fMap.find(V);
+  if (FI == fMap.end()) return -1;
+  
+  return FI->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;
+  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");
+}
 
-  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++;
-  }
 
-  SC_DEBUG("  Inserting value [" << VTy << "] = " << V << " slot=" <<
-           DestSlot << " [");
+/// 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((isa<GlobalVariable>(V) ? 'G' : (isa<Function>(V) ? 'F' : 'o')));
-  SC_DEBUG("]\n");
-  return DestSlot;
-}
+  SC_DEBUG("  Inserting value [" << VTy << "] = " << V << " slot=" <<
+           DestSlot << " [o]\n");
+}