[llvm-commits] [vector_llvm] CVS: llvm/lib/VMCore/AsmWriter.cpp Function.cpp Instructions.cpp Mangler.cpp SymbolTable.cpp Type.cpp Verifier.cpp

Robert Bocchino bocchino at cs.uiuc.edu
Wed Nov 16 10:33:12 PST 2005



Changes in directory llvm/lib/VMCore:

AsmWriter.cpp updated: 1.181.2.1 -> 1.181.2.2
Function.cpp updated: 1.95 -> 1.95.4.1
Instructions.cpp updated: 1.26.2.1 -> 1.26.2.2
Mangler.cpp updated: 1.19 -> 1.19.2.1
SymbolTable.cpp updated: 1.59 -> 1.59.4.1
Type.cpp updated: 1.129.2.1 -> 1.129.2.2
Verifier.cpp updated: 1.134.2.1 -> 1.134.2.2
---
Log message:

Merged mainline into Vector LLVM branch


---
Diffs of the changes:  (+270 -220)

 AsmWriter.cpp    |   15 ++-
 Function.cpp     |    7 -
 Instructions.cpp |   14 +-
 Mangler.cpp      |  171 +++++++++++++++++++++++-----------
 SymbolTable.cpp  |    2 
 Type.cpp         |  273 +++++++++++++++++++++++--------------------------------
 Verifier.cpp     |    8 +
 7 files changed, 270 insertions(+), 220 deletions(-)


Index: llvm/lib/VMCore/AsmWriter.cpp
diff -u llvm/lib/VMCore/AsmWriter.cpp:1.181.2.1 llvm/lib/VMCore/AsmWriter.cpp:1.181.2.2
--- llvm/lib/VMCore/AsmWriter.cpp:1.181.2.1	Tue Oct 18 14:21:57 2005
+++ llvm/lib/VMCore/AsmWriter.cpp	Wed Nov 16 12:32:57 2005
@@ -839,7 +839,12 @@
     assert(C &&  "GlobalVar initializer isn't constant?");
     writeOperand(GV->getInitializer(), false, isa<GlobalValue>(C));
   }
-
+  
+  if (GV->hasSection())
+    Out << ", section \"" << GV->getSection() << '"';
+  if (GV->getAlignment())
+    Out << ", align " << GV->getAlignment();
+  
   printInfoComment(*GV);
   Out << "\n";
 }
@@ -947,6 +952,11 @@
   }
   Out << ')';
 
+  if (F->hasSection())
+    Out << " section \"" << F->getSection() << '"';
+  if (F->getAlignment())
+    Out << " align " << F->getAlignment();
+
   if (F->isExternal()) {
     Out << "\n";
   } else {
@@ -1181,6 +1191,9 @@
       Out << ',';
       writeOperand(AI->getArraySize(), true);
     }
+    if (AI->getAlignment()) {
+      Out << ", align " << AI->getAlignment();
+    }
   } else if (isa<CastInst>(I)) {
     if (Operand) writeOperand(Operand, true);   // Work with broken code
     Out << " to ";


Index: llvm/lib/VMCore/Function.cpp
diff -u llvm/lib/VMCore/Function.cpp:1.95 llvm/lib/VMCore/Function.cpp:1.95.4.1
--- llvm/lib/VMCore/Function.cpp:1.95	Fri May  6 15:26:43 2005
+++ llvm/lib/VMCore/Function.cpp	Wed Nov 16 12:32:58 2005
@@ -243,9 +243,10 @@
     if (getName() == "llvm.pcmarker")  return Intrinsic::pcmarker;
     break;
   case 'r':
-    if (getName() == "llvm.returnaddress")  return Intrinsic::returnaddress;
-    if (getName() == "llvm.readport")       return Intrinsic::readport;
-    if (getName() == "llvm.readio")         return Intrinsic::readio;
+    if (getName() == "llvm.returnaddress")    return Intrinsic::returnaddress;
+    if (getName() == "llvm.readport")         return Intrinsic::readport;
+    if (getName() == "llvm.readio")           return Intrinsic::readio;
+    if (getName() == "llvm.readcyclecounter") return Intrinsic::readcyclecounter;
     break;
   case 's':
     if (getName() == "llvm.setjmp")     return Intrinsic::setjmp;


Index: llvm/lib/VMCore/Instructions.cpp
diff -u llvm/lib/VMCore/Instructions.cpp:1.26.2.1 llvm/lib/VMCore/Instructions.cpp:1.26.2.2
--- llvm/lib/VMCore/Instructions.cpp:1.26.2.1	Tue Oct 18 14:21:57 2005
+++ llvm/lib/VMCore/Instructions.cpp	Wed Nov 16 12:32:58 2005
@@ -495,18 +495,20 @@
 }
 
 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
-                               const std::string &Name,
+                               unsigned Align, const std::string &Name,
                                Instruction *InsertBefore)
   : UnaryInstruction(PointerType::get(Ty), iTy, getAISize(ArraySize),
-                     Name, InsertBefore) {
+                     Name, InsertBefore), Alignment(Align) {
+  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
 }
 
 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
-                               const std::string &Name,
+                               unsigned Align, const std::string &Name,
                                BasicBlock *InsertAtEnd)
   : UnaryInstruction(PointerType::get(Ty), iTy, getAISize(ArraySize),
-                     Name, InsertAtEnd) {
+                     Name, InsertAtEnd), Alignment(Align) {
+  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
 }
 
@@ -522,12 +524,12 @@
 
 AllocaInst::AllocaInst(const AllocaInst &AI)
   : AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0),
-                   Instruction::Alloca) {
+                   Instruction::Alloca, AI.getAlignment()) {
 }
 
 MallocInst::MallocInst(const MallocInst &MI)
   : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
-                   Instruction::Malloc) {
+                   Instruction::Malloc, MI.getAlignment()) {
 }
 
 //===----------------------------------------------------------------------===//


Index: llvm/lib/VMCore/Mangler.cpp
diff -u llvm/lib/VMCore/Mangler.cpp:1.19 llvm/lib/VMCore/Mangler.cpp:1.19.2.1
--- llvm/lib/VMCore/Mangler.cpp:1.19	Thu Oct 13 20:28:34 2005
+++ llvm/lib/VMCore/Mangler.cpp	Wed Nov 16 12:32:58 2005
@@ -12,8 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Mangler.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
-#include "llvm/Type.h"
 #include "llvm/ADT/StringExtras.h"
 using namespace llvm;
 
@@ -22,7 +22,8 @@
 }
 
 static std::string MangleLetter(unsigned char C) {
-  return std::string("_")+HexDigit(C >> 4) + HexDigit(C & 15) + "_";
+  char Result[] = { '_', HexDigit(C >> 4), HexDigit(C & 15), '_', 0 };
+  return Result;
 }
 
 /// makeNameProper - We don't want identifier names non-C-identifier characters
@@ -30,24 +31,71 @@
 ///
 std::string Mangler::makeNameProper(const std::string &X, const char *Prefix) {
   std::string Result;
-
-  // If X does not start with (char)1, add the prefix.
-  std::string::const_iterator I = X.begin();
-  if (*I != 1)
-    Result = Prefix;
-  else
-    ++I;  // Skip over the marker.
+  if (X.empty()) return X;  // Empty names are uniqued by the caller.
   
-  // Mangle the first letter specially, don't allow numbers...
-  if (*I >= '0' && *I <= '9')
-    Result += MangleLetter(*I++);
-
-  for (std::string::const_iterator E = X.end(); I != E; ++I)
-    if ((*I < 'a' || *I > 'z') && (*I < 'A' || *I > 'Z') &&
-        (*I < '0' || *I > '9') && *I != '_' && *I != '$')
-      Result += MangleLetter(*I);
+  if (!UseQuotes) {
+    // If X does not start with (char)1, add the prefix.
+    std::string::const_iterator I = X.begin();
+    if (*I != 1)
+      Result = Prefix;
+    else
+      ++I;  // Skip over the marker.
+    
+    // Mangle the first letter specially, don't allow numbers.
+    if (*I >= '0' && *I <= '9')
+      Result += MangleLetter(*I++);
+
+    for (std::string::const_iterator E = X.end(); I != E; ++I) {
+      if (!isCharAcceptable(*I))
+        Result += MangleLetter(*I);
+      else
+        Result += *I;
+    }
+  } else {
+    bool NeedsQuotes = false;
+    
+    std::string::const_iterator I = X.begin();
+    if (*I == 1)
+      ++I;  // Skip over the marker.
+
+    // If the first character is a number, we need quotes.
+    if (*I >= '0' && *I <= '9')
+      NeedsQuotes = true;
+    
+    // Do an initial scan of the string, checking to see if we need quotes or
+    // to escape a '"' or not.
+    if (!NeedsQuotes)
+      for (std::string::const_iterator E = X.end(); I != E; ++I)
+        if (!isCharAcceptable(*I)) {
+          NeedsQuotes = true;
+          break;
+        }
+    
+    // In the common case, we don't need quotes.  Handle this quickly.
+    if (!NeedsQuotes) {
+      if (*X.begin() != 1)
+        return Prefix+X;
+      else
+        return X.substr(1);
+    }
+    
+    // Otherwise, construct the string the expensive way.
+    I = X.begin();
+    
+    // If X does not start with (char)1, add the prefix.
+    if (*I != 1)
+      Result = Prefix;
     else
-      Result += *I;
+      ++I;   // Skip the marker if present.
+      
+    for (std::string::const_iterator E = X.end(); I != E; ++I) {
+      if (*I == '"')
+        Result += "_QQ_";
+      else
+        Result += *I;
+    }
+    Result = '"' + Result + '"';
+  }
   return Result;
 }
 
@@ -59,48 +107,50 @@
   return E;
 }
 
-
 std::string Mangler::getValueName(const Value *V) {
-  // Check to see whether we've already named V.
-  ValueMap::iterator VI = Memo.find(V);
-  if (VI != Memo.end()) {
-    return VI->second; // Return the old name for V.
-  }
+  if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
+    return getValueName(GV);
+  
+  std::string &Name = Memo[V];
+  if (!Name.empty())
+    return Name;       // Return the already-computed name for V.
+  
+  // Always mangle local names.
+  Name = "ltmp_" + utostr(Count++) + "_" + utostr(getTypeID(V->getType()));
+  return Name;
+}
 
-  std::string name;
-  if (V->hasName()) { // Print out the label if it exists...
-    // Name mangling occurs as follows:
-    // - If V is an intrinsic function, do not change name at all
-    // - If V is not a global, mangling always occurs.
-    // - Otherwise, mangling occurs when any of the following are true:
-    //   1) V has internal linkage
-    //   2) V's name would collide if it is not mangled.
-    //
-    const GlobalValue* gv = dyn_cast<GlobalValue>(V);
-    if (gv && isa<Function>(gv) && cast<Function>(gv)->getIntrinsicID()) {
-      name = gv->getName(); // Is an intrinsic function
-    } else if (gv && !gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
-      name = makeNameProper(gv->getName(), Prefix);
-    } else {
-      // Non-global, or global with internal linkage / colliding name
-      // -> mangle.
-      unsigned TypeUniqueID = getTypeID(V->getType());
-      name = "l" + utostr(TypeUniqueID) + "_" + makeNameProper(V->getName());
-    }
+
+std::string Mangler::getValueName(const GlobalValue *GV) {
+  // Check to see whether we've already named V.
+  std::string &Name = Memo[GV];
+  if (!Name.empty())
+    return Name;       // Return the already-computed name for V.
+
+  // Name mangling occurs as follows:
+  // - If V is an intrinsic function, do not change name at all
+  // - Otherwise, mangling occurs if global collides with existing name.
+  if (isa<Function>(GV) && cast<Function>(GV)->getIntrinsicID()) {
+    Name = GV->getName(); // Is an intrinsic function
+  } else if (!GV->hasName()) {
+    // Must mangle the global into a unique ID.
+    unsigned TypeUniqueID = getTypeID(GV->getType());
+    static unsigned GlobalID = 0;
+    Name = "__unnamed_" + utostr(TypeUniqueID) + "_" + utostr(GlobalID++);
+  } else if (!MangledGlobals.count(GV)) {
+    Name = makeNameProper(GV->getName(), Prefix);
   } else {
-    name = "ltmp_" + utostr(Count++) + "_" + utostr(getTypeID(V->getType()));
+    unsigned TypeUniqueID = getTypeID(GV->getType());
+    Name = "l" + utostr(TypeUniqueID) + "_" + makeNameProper(GV->getName());
   }
 
-  Memo[V] = name;
-  return name;
+  return Name;
 }
 
 void Mangler::InsertName(GlobalValue *GV,
                          std::map<std::string, GlobalValue*> &Names) {
-  if (!GV->hasName()) {   // We must mangle unnamed globals.
-    MangledGlobals.insert(GV);
+  if (!GV->hasName())   // We must mangle unnamed globals.
     return;
-  }
 
   // Figure out if this is already used.
   GlobalValue *&ExistingValue = Names[GV->getName()];
@@ -119,8 +169,25 @@
 }
 
 
-Mangler::Mangler(Module &m, const char *prefix)
-  : M(m), Prefix(prefix), TypeCounter(0), Count(0) {
+Mangler::Mangler(Module &M, const char *prefix)
+  : Prefix(prefix), UseQuotes(false), Count(0), TypeCounter(0) {
+  std::fill(AcceptableChars, 
+          AcceptableChars+sizeof(AcceptableChars)/sizeof(AcceptableChars[0]),
+            0);
+
+  // Letters and numbers are acceptable.
+  for (unsigned char X = 'a'; X <= 'z'; ++X)
+    markCharAcceptable(X);
+  for (unsigned char X = 'A'; X <= 'Z'; ++X)
+    markCharAcceptable(X);
+  for (unsigned char X = '0'; X <= '9'; ++X)
+    markCharAcceptable(X);
+  
+  // These chars are acceptable.
+  markCharAcceptable('_');
+  markCharAcceptable('$');
+  markCharAcceptable('.');
+    
   // Calculate which global values have names that will collide when we throw
   // away type information.
   std::map<std::string, GlobalValue*> Names;


Index: llvm/lib/VMCore/SymbolTable.cpp
diff -u llvm/lib/VMCore/SymbolTable.cpp:1.59 llvm/lib/VMCore/SymbolTable.cpp:1.59.4.1
--- llvm/lib/VMCore/SymbolTable.cpp:1.59	Thu Apr 21 18:46:51 2005
+++ llvm/lib/VMCore/SymbolTable.cpp	Wed Nov 16 12:32:58 2005
@@ -269,12 +269,12 @@
     value_iterator B = Plane.begin(), Bend = Plane.end();
     while (B != Bend) {   // Found nonempty type plane!
       Value *V = B->second;
+      ++B;
       if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
         // Set name to "", removing from symbol table!
         V->setName("");
         RemovedSymbol = true;
       }
-      ++B;
     }
   }
 


Index: llvm/lib/VMCore/Type.cpp
diff -u llvm/lib/VMCore/Type.cpp:1.129.2.1 llvm/lib/VMCore/Type.cpp:1.129.2.2
--- llvm/lib/VMCore/Type.cpp:1.129.2.1	Tue Oct 18 14:21:58 2005
+++ llvm/lib/VMCore/Type.cpp	Wed Nov 16 12:32:58 2005
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/SCCIterator.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
 #include <algorithm>
 #include <iostream>
 using namespace llvm;
@@ -42,14 +43,13 @@
 static std::map<const Type*, std::string> ConcreteTypeDescriptions;
 static std::map<const Type*, std::string> AbstractTypeDescriptions;
 
-Type::Type( const std::string& name, TypeID id )
-  : RefCount(0), ForwardType(0) {
-  if (!name.empty())
-    ConcreteTypeDescriptions[this] = name;
-  ID = id;
-  Abstract = false;
+Type::Type(const char *Name, TypeID id)
+  : ID(id), Abstract(false),  RefCount(0), ForwardType(0) {
+  assert(Name && Name[0] && "Should use other ctor if no name!");
+  ConcreteTypeDescriptions[this] = Name;
 }
 
+
 const Type *Type::getPrimitiveType(TypeID IDNumber) {
   switch (IDNumber) {
   case VoidTyID  : return VoidTy;
@@ -213,6 +213,14 @@
   return ForwardType;
 }
 
+void Type::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
+  abort();
+}
+void Type::typeBecameConcrete(const DerivedType *AbsTy) {
+  abort();
+}
+
+
 // getTypeDescription - This is a recursive function that walks a type hierarchy
 // calculating the description for a type.
 //
@@ -291,12 +299,6 @@
     Result += getTypeDescription(ATy->getElementType(), TypeStack) + "]";
     break;
   }
-  case Type::StreamTyID: {
-    const StreamType *STy = cast<StreamType>(Ty);
-    Result = "[stream of ";
-    Result += getTypeDescription(STy->getElementType(), TypeStack) + "]";
-    break;
-  }
   case Type::VectorTyID: {
     const VectorType *VTy = cast<VectorType>(Ty);
     Result = "[vector of ";
@@ -453,12 +455,6 @@
   setAbstract(E->isAbstract());
 }
 
-StreamType::StreamType(const Type *E)
-  : SequentialType(StreamTyID, E) {
-  assert((E->isIntegral() || E->isFloatingPoint() || isa<FixedVectorType>(E)) && 
-         "Elements of a StreamType must be a primitive or fixed vector type!");
-}
-
 VectorType::VectorType(const Type *E, bool fixed)
   : SequentialType(fixed ? FixedVectorTyID : VectorTyID, E) {
   assert((E->isIntegral() || E->isFloatingPoint()) && 
@@ -697,15 +693,9 @@
 //                       Derived Type Factory Functions
 //===----------------------------------------------------------------------===//
 
-// TypeMap - Make sure that only one instance of a particular type may be
-// created on any given run of the compiler... note that this involves updating
-// our map if an abstract type gets refined somehow.
-//
 namespace llvm {
-template<class ValType, class TypeClass>
-class TypeMap {
-  std::map<ValType, PATypeHolder> Map;
-
+class TypeMapBase {
+protected:
   /// TypesByHash - Keep track of types by their structure hash value.  Note
   /// that we only keep track of types that have cycles through themselves in
   /// this map.
@@ -714,14 +704,48 @@
 
   friend void Type::clearAllTypeMaps();
 
-private:
-  void clear(std::vector<Type *> &DerivedTypes) {
-    for (typename std::map<ValType, PATypeHolder>::iterator I = Map.begin(),
-         E = Map.end(); I != E; ++I)
-      DerivedTypes.push_back(I->second.get());
-    TypesByHash.clear();
-    Map.clear();
+public:
+  void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) {
+    std::multimap<unsigned, PATypeHolder>::iterator I =
+    TypesByHash.lower_bound(Hash);
+    while (I->second != Ty) {
+      ++I;
+      assert(I != TypesByHash.end() && I->first == Hash);
+    }
+    TypesByHash.erase(I);
+  }
+  
+  /// TypeBecameConcrete - When Ty gets a notification that TheType just became
+  /// concrete, drop uses and make Ty non-abstract if we should.
+  void TypeBecameConcrete(DerivedType *Ty, const DerivedType *TheType) {
+    // If the element just became concrete, remove 'ty' from the abstract
+    // type user list for the type.  Do this for as many times as Ty uses
+    // OldType.
+    for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
+         I != E; ++I)
+      if (I->get() == TheType)
+        TheType->removeAbstractTypeUser(Ty);
+    
+    // If the type is currently thought to be abstract, rescan all of our
+    // subtypes to see if the type has just become concrete!  Note that this
+    // may send out notifications to AbstractTypeUsers that types become
+    // concrete.
+    if (Ty->isAbstract())
+      Ty->PromoteAbstractToConcrete();
   }
+};
+}
+
+
+// TypeMap - Make sure that only one instance of a particular type may be
+// created on any given run of the compiler... note that this involves updating
+// our map if an abstract type gets refined somehow.
+//
+namespace llvm {
+template<class ValType, class TypeClass>
+class TypeMap : public TypeMapBase {
+  std::map<ValType, PATypeHolder> Map;
+
 public:
   typedef typename std::map<ValType, PATypeHolder>::iterator iterator;
   ~TypeMap() { print("ON EXIT"); }
@@ -738,29 +762,29 @@
     TypesByHash.insert(std::make_pair(ValType::hashTypeStructure(Ty), Ty));
     print("add");
   }
-
-  void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) {
-    std::multimap<unsigned, PATypeHolder>::iterator I =
-      TypesByHash.lower_bound(Hash);
-    while (I->second != Ty) {
-      ++I;
-      assert(I != TypesByHash.end() && I->first == Hash);
-    }
-    TypesByHash.erase(I);
+  
+  void clear(std::vector<Type *> &DerivedTypes) {
+    for (typename std::map<ValType, PATypeHolder>::iterator I = Map.begin(),
+         E = Map.end(); I != E; ++I)
+      DerivedTypes.push_back(I->second.get());
+    TypesByHash.clear();
+    Map.clear();
   }
 
-  /// finishRefinement - This method is called after we have updated an existing
-  /// type with its new components.  We must now either merge the type away with
+ /// RefineAbstractType - This method is called after we have merged a type
+  /// with another one.  We must now either merge the type away with
   /// some other type or reinstall it in the map with it's new configuration.
-  /// The specified iterator tells us what the type USED to look like.
-  void finishRefinement(TypeClass *Ty, const DerivedType *OldType,
+  void RefineAbstractType(TypeClass *Ty, const DerivedType *OldType,
                         const Type *NewType) {
-    assert((Ty->isAbstract() || !OldType->isAbstract()) &&
-           "Refining a non-abstract type!");
 #ifdef DEBUG_MERGE_TYPES
-    std::cerr << "refineAbstractTy(" << (void*)OldType << "[" << *OldType
-              << "], " << (void*)NewType << " [" << *NewType << "])\n";
+    std::cerr << "RefineAbstractType(" << (void*)OldType << "[" << *OldType
+    << "], " << (void*)NewType << " [" << *NewType << "])\n";
 #endif
+    
+    // Otherwise, we are changing one subelement type into another.  Clearly the
+    // OldType must have been abstract, making us abstract.
+    assert(Ty->isAbstract() && "Refining a non-abstract type!");
+    assert(OldType != NewType);
 
     // Make a temporary type holder for the type so that it doesn't disappear on
     // us when we erase the entry from the map.
@@ -768,7 +792,8 @@
 
     // The old record is now out-of-date, because one of the children has been
     // updated.  Remove the obsolete entry from the map.
-    Map.erase(ValType::get(Ty));
+    unsigned NumErased = Map.erase(ValType::get(Ty));
+    assert(NumErased && "Element not found!");
 
     // Remember the structural hash for the type before we start hacking on it,
     // in case we need it later.
@@ -776,25 +801,22 @@
 
     // Find the type element we are refining... and change it now!
     for (unsigned i = 0, e = Ty->ContainedTys.size(); i != e; ++i)
-      if (Ty->ContainedTys[i] == OldType) {
-        Ty->ContainedTys[i].removeUserFromConcrete();
+      if (Ty->ContainedTys[i] == OldType)
         Ty->ContainedTys[i] = NewType;
-      }
-
-    unsigned TypeHash = ValType::hashTypeStructure(Ty);
-
+    unsigned NewTypeHash = ValType::hashTypeStructure(Ty);
+    
     // If there are no cycles going through this node, we can do a simple,
     // efficient lookup in the map, instead of an inefficient nasty linear
     // lookup.
-    if (!Ty->isAbstract() || !TypeHasCycleThroughItself(Ty)) {
+    if (!TypeHasCycleThroughItself(Ty)) {
       typename std::map<ValType, PATypeHolder>::iterator I;
       bool Inserted;
 
-      ValType V = ValType::get(Ty);
-      tie(I, Inserted) = Map.insert(std::make_pair(V, Ty));
+      tie(I, Inserted) = Map.insert(std::make_pair(ValType::get(Ty), Ty));
       if (!Inserted) {
+        assert(OldType != NewType);
         // Refined to a different type altogether?
-        RemoveFromTypesByHash(TypeHash, Ty);
+        RemoveFromTypesByHash(OldTypeHash, Ty);
 
         // We already have this type in the table.  Get rid of the newly refined
         // type.
@@ -802,7 +824,6 @@
         Ty->refineAbstractTypeTo(NewTy);
         return;
       }
-
     } else {
       // Now we check to see if there is an existing entry in the table which is
       // structurally identical to the newly refined type.  If so, this type
@@ -812,44 +833,44 @@
       tie(I, E) = TypesByHash.equal_range(OldTypeHash);
       Entry = E;
       for (; I != E; ++I) {
-        if (I->second != Ty) {
+        if (I->second == Ty) {
+          // Remember the position of the old type if we see it in our scan.
+          Entry = I;
+        } else {
           if (TypesEqual(Ty, I->second)) {
-            assert(Ty->isAbstract() && "Replacing a non-abstract type?");
             TypeClass *NewTy = cast<TypeClass>((Type*)I->second.get());
 
             if (Entry == E) {
-              // Find the location of Ty in the TypesByHash structure.
+              // Find the location of Ty in the TypesByHash structure if we
+              // haven't seen it already.
               while (I->second != Ty) {
                 ++I;
                 assert(I != E && "Structure doesn't contain type??");
               }
               Entry = I;
             }
-
             TypesByHash.erase(Entry);
             Ty->refineAbstractTypeTo(NewTy);
             return;
           }
-        } else {
-          // Remember the position of
-          Entry = I;
         }
       }
 
-
       // If there is no existing type of the same structure, we reinsert an
       // updated record into the map.
       Map.insert(std::make_pair(ValType::get(Ty), Ty));
     }
 
     // If the hash codes differ, update TypesByHash
-    if (TypeHash != OldTypeHash) {
+    if (NewTypeHash != OldTypeHash) {
       RemoveFromTypesByHash(OldTypeHash, Ty);
-      TypesByHash.insert(std::make_pair(TypeHash, Ty));
+      TypesByHash.insert(std::make_pair(NewTypeHash, Ty));
     }
-
+    
     // If the type is currently thought to be abstract, rescan all of our
-    // subtypes to see if the type has just become concrete!
+    // subtypes to see if the type has just become concrete!  Note that this
+    // may send out notifications to AbstractTypeUsers that types become
+    // concrete.
     if (Ty->isAbstract())
       Ty->PromoteAbstractToConcrete();
   }
@@ -1025,6 +1046,7 @@
 
 FixedVectorType *FixedVectorType::get(const Type *ElementType, unsigned NumElements) {
   assert(ElementType && "Can't get fixed-length vector of null types!");
+  //assert(isPowerOf2_32(NumElements) && "Vector length should be a power of 2!");
 
   FixedVectorValType PVT(ElementType, NumElements);
   FixedVectorType *PT = FixedVectorTypes.get(PVT);
@@ -1148,7 +1170,6 @@
   return PT;
 }
 
-
 //===----------------------------------------------------------------------===//
 // Vector Type Factory...
 //
@@ -1198,54 +1219,6 @@
 
 
 //===----------------------------------------------------------------------===//
-// Stream Type Factory...
-//
-namespace llvm {
-class StreamValType {
-  const Type *ValTy;
-public:
-  StreamValType(const Type *val) : ValTy(val) {}
-
-  static StreamValType get(const StreamType *AT) {
-    return StreamValType(AT->getElementType());
-  }
-
-  static unsigned hashTypeStructure(const StreamType *AT) {
-    return AT->getElementType()->getTypeID(); // ???
-  }
-
-  // Subclass should override this... to update self as usual
-  void doRefinement(const DerivedType *OldType, const Type *NewType) {
-    assert(ValTy == OldType);
-    ValTy = NewType;
-  }
-
-  inline bool operator<(const StreamValType &MTV) const {
-    return ValTy < MTV.ValTy;
-  }
-};
-}
-
-static TypeMap<StreamValType, StreamType> StreamTypes;
-
-StreamType *StreamType::get(const Type *ElementType) {
-  assert(ElementType && "Can't get vector of null types!");
-
-  StreamValType AVT(ElementType);
-  StreamType *AT = StreamTypes.get(AVT);
-  if (AT) return AT;           // Found a match, return it!
-
-  // Value not found.  Derive a new type!
-  StreamTypes.add(AVT, AT = new StreamType(ElementType));
-
-#ifdef DEBUG_MERGE_TYPES
-  std::cerr << "Derived new type: " << *AT << "\n";
-#endif
-  return AT;
-}
-
-
-//===----------------------------------------------------------------------===//
 //                     Derived Type Refinement Functions
 //===----------------------------------------------------------------------===//
 
@@ -1254,7 +1227,7 @@
 // the PATypeHandle class.  When there are no users of the abstract type, it
 // is annihilated, because there is no way to get a reference to it ever again.
 //
-void DerivedType::removeAbstractTypeUser(AbstractTypeUser *U) const {
+void Type::removeAbstractTypeUser(AbstractTypeUser *U) const {
   // Search from back to front because we will notify users from back to
   // front.  Also, it is likely that there will be a stack like behavior to
   // users that register and unregister users.
@@ -1379,11 +1352,11 @@
 //
 void FunctionType::refineAbstractType(const DerivedType *OldType,
                                       const Type *NewType) {
-  FunctionTypes.finishRefinement(this, OldType, NewType);
+  FunctionTypes.RefineAbstractType(this, OldType, NewType);
 }
 
 void FunctionType::typeBecameConcrete(const DerivedType *AbsTy) {
-  refineAbstractType(AbsTy, AbsTy);
+  FunctionTypes.TypeBecameConcrete(this, AbsTy);
 }
 
 
@@ -1393,24 +1366,33 @@
 //
 void ArrayType::refineAbstractType(const DerivedType *OldType,
                                    const Type *NewType) {
-  ArrayTypes.finishRefinement(this, OldType, NewType);
+  ArrayTypes.RefineAbstractType(this, OldType, NewType);
 }
 
 void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) {
-  refineAbstractType(AbsTy, AbsTy);
+  ArrayTypes.TypeBecameConcrete(this, AbsTy);
 }
 
 // refineAbstractType - Called when a contained type is found to be more
 // concrete - this could potentially change us from an abstract type to a
 // concrete type.
 //
+void VectorType::refineAbstractType(const DerivedType *OldType,
+                                   const Type *NewType) {
+  VectorTypes.RefineAbstractType(this, OldType, NewType);
+}
+
+void VectorType::typeBecameConcrete(const DerivedType *AbsTy) {
+  VectorTypes.TypeBecameConcrete(this, AbsTy);
+}
+
 void FixedVectorType::refineAbstractType(const DerivedType *OldType,
                                    const Type *NewType) {
-  FixedVectorTypes.finishRefinement(this, OldType, NewType);
+  FixedVectorTypes.RefineAbstractType(this, OldType, NewType);
 }
 
 void FixedVectorType::typeBecameConcrete(const DerivedType *AbsTy) {
-  refineAbstractType(AbsTy, AbsTy);
+  FixedVectorTypes.TypeBecameConcrete(this, AbsTy);
 }
 
 // refineAbstractType - Called when a contained type is found to be more
@@ -1419,11 +1401,11 @@
 //
 void StructType::refineAbstractType(const DerivedType *OldType,
                                     const Type *NewType) {
-  StructTypes.finishRefinement(this, OldType, NewType);
+  StructTypes.RefineAbstractType(this, OldType, NewType);
 }
 
 void StructType::typeBecameConcrete(const DerivedType *AbsTy) {
-  refineAbstractType(AbsTy, AbsTy);
+  StructTypes.TypeBecameConcrete(this, AbsTy);
 }
 
 // refineAbstractType - Called when a contained type is found to be more
@@ -1432,24 +1414,11 @@
 //
 void PointerType::refineAbstractType(const DerivedType *OldType,
                                      const Type *NewType) {
-  PointerTypes.finishRefinement(this, OldType, NewType);
+  PointerTypes.RefineAbstractType(this, OldType, NewType);
 }
 
 void PointerType::typeBecameConcrete(const DerivedType *AbsTy) {
-  refineAbstractType(AbsTy, AbsTy);
-}
-
-// refineAbstractType - Called when a contained type is found to be more
-// concrete - this could potentially change us from an abstract type to a
-// concrete type.
-//
-void VectorType::refineAbstractType(const DerivedType *OldType,
-				   const Type *NewType) {
-  VectorTypes.finishRefinement(this, OldType, NewType);
-}
-
-void VectorType::typeBecameConcrete(const DerivedType *AbsTy) {
-  refineAbstractType(AbsTy, AbsTy);
+  PointerTypes.TypeBecameConcrete(this, AbsTy);
 }
 
 
@@ -1457,15 +1426,6 @@
 // concrete - this could potentially change us from an abstract type to a
 // concrete type.
 //
-void StreamType::refineAbstractType(const DerivedType *OldType,
-				   const Type *NewType) {
-  StreamTypes.finishRefinement(this, OldType, NewType);
-}
-
-void StreamType::typeBecameConcrete(const DerivedType *AbsTy) {
-  refineAbstractType(AbsTy, AbsTy);
-}
-
 
 bool SequentialType::indexValid(const Value *V) const {
   const Type *Ty = V->getType();
@@ -1505,7 +1465,6 @@
   PointerTypes.clear(DerivedTypes);
   StructTypes.clear(DerivedTypes);
   ArrayTypes.clear(DerivedTypes);
-  StreamTypes.clear(DerivedTypes);
   VectorTypes.clear(DerivedTypes);
   FixedVectorTypes.clear(DerivedTypes);
 


Index: llvm/lib/VMCore/Verifier.cpp
diff -u llvm/lib/VMCore/Verifier.cpp:1.134.2.1 llvm/lib/VMCore/Verifier.cpp:1.134.2.2
--- llvm/lib/VMCore/Verifier.cpp:1.134.2.1	Tue Oct 18 14:21:58 2005
+++ llvm/lib/VMCore/Verifier.cpp	Wed Nov 16 12:32:58 2005
@@ -733,6 +733,14 @@
     NumArgs = 2;
     break;
 
+  case Intrinsic::readcyclecounter:
+    Assert1(FT->getNumParams() == 0,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == Type::ULongTy,
+            "Return type is not ulong!", IF);
+    NumArgs = 0;
+    break;
+
   case Intrinsic::ctpop:
   case Intrinsic::ctlz:
   case Intrinsic::cttz:






More information about the llvm-commits mailing list