Fix a bug found exposed by: Regression/Other/2004-08-20-PackedControlFlow.ll
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index df5cabc75697289c429dd6a398ed3a7cf047bf3e..b109cb006eb6cfc9453b4d251a42514d9b0a3a10 100644 (file)
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instruction.h"
-#include "llvm/iMemory.h"
-#include "llvm/iTerminators.h"
-#include "llvm/iPHINode.h"
-#include "llvm/iOther.h"
+#include "llvm/Instructions.h"
 #include "llvm/Module.h"
 #include "llvm/SymbolTable.h"
 #include "llvm/Assembly/Writer.h"
@@ -95,7 +92,10 @@ public:
 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; }
+  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 
@@ -141,6 +141,7 @@ public:
 
   /// @brief The function for which we are holding slot numbers
   const Function* TheFunction;
+  bool FunctionProcessed;
 
   /// @brief The TypePlanes map for the module level data
   TypedPlanes mMap;
@@ -322,6 +323,13 @@ static void calcTypeName(const Type *Ty,
     Result += "]";
     break;
   }
+  case Type::PackedTyID: {
+    const PackedType *PTy = cast<PackedType>(Ty);
+    Result += "<" + utostr(PTy->getNumElements()) + " x ";
+    calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result);
+    Result += ">";
+    break;
+  }
   case Type::OpaqueTyID:
     Result += "opaque";
     break;
@@ -491,6 +499,22 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV,
     }
 
     Out << " }";
+  } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(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),
+                             PrintName, TypeTable, Machine);
+      for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
+          Out << ", ";
+          printTypeInt(Out, ETy, TypeTable);
+          WriteAsOperandInternal(Out, CP->getOperand(i), PrintName,
+                                 TypeTable, Machine);
+      }
+      Out << " >";
   } else if (isa<ConstantPointerNull>(CV)) {
     Out << "null";
 
@@ -703,7 +727,11 @@ 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 OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
+  } else if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
+    Out << '<' << PTy->getNumElements() << " x ";
+    printType(PTy->getElementType()) << '>';
+  }
+  else if (const OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
     Out << "opaque";
   } else {
     if (!Ty->isPrimitiveType())
@@ -1266,6 +1294,7 @@ CachedWriter& CachedWriter::operator<<(const Type &Ty) {
 SlotMachine::SlotMachine(const Module *M) 
   : TheModule(M)    ///< Saved for lazy initialization.
   , TheFunction(0)
+  , FunctionProcessed(false)
   , mMap()
   , mTypes()
   , fMap()
@@ -1278,6 +1307,7 @@ SlotMachine::SlotMachine(const Module *M)
 SlotMachine::SlotMachine(const Function *F ) 
   : TheModule( F ? F->getParent() : 0 ) ///< Saved for lazy initialization
   , TheFunction(F) ///< Saved for lazy initialization
+  , FunctionProcessed(false)
   , mMap()
   , mTypes()
   , fMap()
@@ -1290,7 +1320,7 @@ inline void SlotMachine::initialize(void) {
     processModule(); 
     TheModule = 0; ///< Prevent re-processing next time we're called.
   }
-  if ( TheFunction ) { 
+  if ( TheFunction && ! FunctionProcessed) { 
     processFunction(); 
   }
 }
@@ -1334,6 +1364,8 @@ void SlotMachine::processFunction() {
     }
   }
 
+  FunctionProcessed = true;
+
   SC_DEBUG("end processFunction!\n");
 }
 
@@ -1346,6 +1378,7 @@ void SlotMachine::purgeFunction() {
   fMap.clear(); // Simply discard the function level map
   fTypes.clear();
   TheFunction = 0;
+  FunctionProcessed = false;
   SC_DEBUG("end purgeFunction!\n");
 }