[llvm-commits] CVS: llvm/lib/VMCore/AsmWriter.cpp Constants.cpp Instructions.cpp Type.cpp Verifier.cpp

Brian Gaeke gaeke at cs.uiuc.edu
Thu Aug 19 23:01:09 PDT 2004



Changes in directory llvm/lib/VMCore:

AsmWriter.cpp updated: 1.154 -> 1.155
Constants.cpp updated: 1.102 -> 1.103
Instructions.cpp updated: 1.2 -> 1.3
Type.cpp updated: 1.111 -> 1.112
Verifier.cpp updated: 1.116 -> 1.117
---
Log message:

Packed types, brought to you by Brad Jones


---
Diffs of the changes:  (+206 -4)

Index: llvm/lib/VMCore/AsmWriter.cpp
diff -u llvm/lib/VMCore/AsmWriter.cpp:1.154 llvm/lib/VMCore/AsmWriter.cpp:1.155
--- llvm/lib/VMCore/AsmWriter.cpp:1.154	Mon Aug 16 02:46:33 2004
+++ llvm/lib/VMCore/AsmWriter.cpp	Fri Aug 20 01:00:57 2004
@@ -323,6 +323,13 @@
     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;
@@ -492,6 +499,22 @@
     }
 
     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";
 


Index: llvm/lib/VMCore/Constants.cpp
diff -u llvm/lib/VMCore/Constants.cpp:1.102 llvm/lib/VMCore/Constants.cpp:1.103
--- llvm/lib/VMCore/Constants.cpp:1.102	Tue Aug 17 12:28:46 2004
+++ llvm/lib/VMCore/Constants.cpp	Fri Aug 20 01:00:57 2004
@@ -120,6 +120,7 @@
 
   case Type::StructTyID:
   case Type::ArrayTyID:
+  case Type::PackedTyID:
     return ConstantAggregateZero::get(Ty);
   default:
     // Function, Label, or Opaque type?
@@ -268,6 +269,17 @@
   }
 }
 
+ConstantPacked::ConstantPacked(const PackedType *T,
+                               const std::vector<Constant*> &V) : Constant(T) {
+  Operands.reserve(V.size());
+  for (unsigned i = 0, e = V.size(); i != e; ++i) {
+    assert(V[i]->getType() == T->getElementType() ||
+           (T->isAbstract() &&
+            V[i]->getType()->getTypeID() == T->getElementType()->getTypeID()));
+    Operands.push_back(Use(V[i], this));
+  }
+}
+
 ConstantExpr::ConstantExpr(unsigned Opcode, Constant *C, const Type *Ty)
   : Constant(Ty, ConstantExprVal), iType(Opcode) {
   Operands.reserve(1);
@@ -484,6 +496,31 @@
   destroyConstant();
 }
 
+void ConstantPacked::replaceUsesOfWithOnConstant(Value *From, Value *To,
+                                                 bool DisableChecking) {
+  assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
+
+  std::vector<Constant*> Values;
+  Values.reserve(getNumOperands());  // Build replacement array...
+  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+    Constant *Val = getOperand(i);
+    if (Val == From) Val = cast<Constant>(To);
+    Values.push_back(Val);
+  }
+  
+  Constant *Replacement = ConstantPacked::get(getType(), Values);
+  assert(Replacement != this && "I didn't contain From!");
+
+  // Everyone using this now uses the replacement...
+  if (DisableChecking)
+    uncheckedReplaceAllUsesWith(Replacement);
+  else
+    replaceAllUsesWith(Replacement);
+  
+  // Delete the old constant!
+  destroyConstant();  
+}
+
 void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
                                                bool DisableChecking) {
   assert(isa<Constant>(ToV) && "Cannot make Constant refer to non-constant!");
@@ -959,6 +996,61 @@
   destroyConstantImpl();
 }
 
+//---- ConstantPacked::get() implementation...
+//
+namespace llvm {
+  template<>
+  struct ConvertConstantType<ConstantPacked, PackedType> {
+    static void convert(ConstantPacked *OldC, const PackedType *NewTy) {
+      // Make everyone now use a constant of the new type...
+      std::vector<Constant*> C;
+      for (unsigned i = 0, e = OldC->getNumOperands(); i != e; ++i)
+        C.push_back(cast<Constant>(OldC->getOperand(i)));
+      Constant *New = ConstantPacked::get(NewTy, C);
+      assert(New != OldC && "Didn't replace constant??");
+      OldC->uncheckedReplaceAllUsesWith(New);
+      OldC->destroyConstant();    // This constant is now dead, destroy it.
+    }
+  };
+}
+
+static std::vector<Constant*> getValType(ConstantPacked *CP) {
+  std::vector<Constant*> Elements;
+  Elements.reserve(CP->getNumOperands());
+  for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
+    Elements.push_back(CP->getOperand(i));
+  return Elements;
+}
+
+static ValueMap<std::vector<Constant*>, PackedType,
+                ConstantPacked> PackedConstants;
+
+Constant *ConstantPacked::get(const PackedType *Ty,
+                              const std::vector<Constant*> &V) {
+  // If this is an all-zero packed, return a ConstantAggregateZero object
+  if (!V.empty()) {
+    Constant *C = V[0];
+    if (!C->isNullValue())
+      return PackedConstants.getOrCreate(Ty, V);
+    for (unsigned i = 1, e = V.size(); i != e; ++i)
+      if (V[i] != C)
+        return PackedConstants.getOrCreate(Ty, V);
+  }
+  return ConstantAggregateZero::get(Ty);
+}
+
+Constant *ConstantPacked::get(const std::vector<Constant*> &V) {
+  assert(!V.empty() && "Cannot infer type if V is empty");
+  return get(PackedType::get(V.front()->getType(),V.size()), V);
+}
+
+// destroyConstant - Remove the constant from the constant table...
+//
+void ConstantPacked::destroyConstant() {
+  PackedConstants.remove(this);
+  destroyConstantImpl();
+}
+
 //---- ConstantPointerNull::get() implementation...
 //
 


Index: llvm/lib/VMCore/Instructions.cpp
diff -u llvm/lib/VMCore/Instructions.cpp:1.2 llvm/lib/VMCore/Instructions.cpp:1.3
--- llvm/lib/VMCore/Instructions.cpp:1.2	Fri Aug  6 09:33:37 2004
+++ llvm/lib/VMCore/Instructions.cpp	Fri Aug 20 01:00:57 2004
@@ -564,8 +564,10 @@
   case Rem:
     assert(getType() == S1->getType() &&
            "Arithmetic operation should return same type as operands!");
-    assert((getType()->isInteger() || getType()->isFloatingPoint()) && 
-           "Tried to create an arithmetic operation on a non-arithmetic type!");
+    assert((getType()->isInteger() || 
+            getType()->isFloatingPoint() || 
+            isa<PackedType>(getType()) ) && 
+          "Tried to create an arithmetic operation on a non-arithmetic type!");
     break;
   case And: case Or:
   case Xor:


Index: llvm/lib/VMCore/Type.cpp
diff -u llvm/lib/VMCore/Type.cpp:1.111 llvm/lib/VMCore/Type.cpp:1.112
--- llvm/lib/VMCore/Type.cpp:1.111	Tue Jul 13 15:09:51 2004
+++ llvm/lib/VMCore/Type.cpp	Fri Aug 20 01:00:57 2004
@@ -261,6 +261,14 @@
     Result += getTypeDescription(ATy->getElementType(), TypeStack) + "]";
     break;
   }
+  case Type::PackedTyID: {
+    const PackedType *PTy = cast<PackedType>(Ty);
+    unsigned NumElements = PTy->getNumElements();
+    Result = "<";
+    Result += utostr(NumElements) + " x ";
+    Result += getTypeDescription(PTy->getElementType(), TypeStack) + ">";
+    break;
+  }
   default:
     Result = "<error>";
     assert(0 && "Unhandled type in getTypeDescription!");
@@ -397,6 +405,16 @@
   setAbstract(ElType->isAbstract());
 }
 
+PackedType::PackedType(const Type *ElType, unsigned NumEl)
+  : SequentialType(PackedTyID, ElType) {
+  NumElements = NumEl;
+
+  assert(NumEl > 0 && "NumEl of a PackedType must be greater than 0");
+  assert((ElType->isIntegral() || ElType->isFloatingPoint()) && 
+         "Elements of a PackedType must be a primitive type");
+}
+
+
 PointerType::PointerType(const Type *E) : SequentialType(PointerTyID, E) {
   // Calculate whether or not this type is abstract
   setAbstract(E->isAbstract());
@@ -503,6 +521,10 @@
     const ArrayType *ATy2 = cast<ArrayType>(Ty2);
     return ATy->getNumElements() == ATy2->getNumElements() &&
            TypesEqual(ATy->getElementType(), ATy2->getElementType(), EqTypes);
+  } else if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
+    const PackedType *PTy2 = cast<PackedType>(Ty2);
+    return PTy->getNumElements() == PTy2->getNumElements() &&
+           TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes);
   } else if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
     const FunctionType *FTy2 = cast<FunctionType>(Ty2);
     if (FTy->isVarArg() != FTy2->isVarArg() ||
@@ -846,6 +868,56 @@
   return AT;
 }
 
+
+//===----------------------------------------------------------------------===//
+// Packed Type Factory...
+//
+namespace llvm {
+class PackedValType {
+  const Type *ValTy;
+  unsigned Size;
+public:
+  PackedValType(const Type *val, int sz) : ValTy(val), Size(sz) {}
+
+  static PackedValType get(const PackedType *PT) {
+    return PackedValType(PT->getElementType(), PT->getNumElements());
+  }
+
+  static unsigned hashTypeStructure(const PackedType *PT) {
+    return PT->getNumElements();
+  }
+
+  // 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 PackedValType &MTV) const {
+    if (Size < MTV.Size) return true;
+    return Size == MTV.Size && ValTy < MTV.ValTy;
+  }
+};
+}
+static TypeMap<PackedValType, PackedType> PackedTypes;
+
+
+PackedType *PackedType::get(const Type *ElementType, unsigned NumElements) {
+  assert(ElementType && "Can't get packed of null types!");
+
+  PackedValType PVT(ElementType, NumElements);
+  PackedType *PT = PackedTypes.get(PVT);
+  if (PT) return PT;           // Found a match, return it!
+
+  // Value not found.  Derive a new type!
+  PackedTypes.add(PVT, PT = new PackedType(ElementType, NumElements));
+
+#ifdef DEBUG_MERGE_TYPES
+  std::cerr << "Derived new type: " << *PT << "\n";
+#endif
+  return PT;
+}
+
 //===----------------------------------------------------------------------===//
 // Struct Type Factory...
 //
@@ -1107,6 +1179,18 @@
   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 PackedType::refineAbstractType(const DerivedType *OldType,
+                                   const Type *NewType) {
+  PackedTypes.finishRefinement(this, OldType, NewType);
+}
+
+void PackedType::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


Index: llvm/lib/VMCore/Verifier.cpp
diff -u llvm/lib/VMCore/Verifier.cpp:1.116 llvm/lib/VMCore/Verifier.cpp:1.117
--- llvm/lib/VMCore/Verifier.cpp:1.116	Thu Jul 22 00:50:01 2004
+++ llvm/lib/VMCore/Verifier.cpp	Fri Aug 20 01:00:58 2004
@@ -488,8 +488,9 @@
     Assert1(B.getType() == B.getOperand(0)->getType(),
             "Arithmetic operators must have same type for operands and result!",
             &B);
-    Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint(),
-            "Arithmetic operators must have integer or fp type!", &B);
+    Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint() || 
+            isa<PackedType>(B.getType()),
+            "Arithmetic operators must have integer, fp, or packed type!", &B);
   }
   
   visitInstruction(B);






More information about the llvm-commits mailing list