[llvm-commits] [llvm] r148741 - in /llvm/trunk: include/llvm/Constants.h include/llvm/Value.h lib/VMCore/Constants.cpp lib/VMCore/LLVMContextImpl.cpp lib/VMCore/LLVMContextImpl.h

Chris Lattner sabre at nondot.org
Mon Jan 23 14:57:10 PST 2012


Author: lattner
Date: Mon Jan 23 16:57:10 2012
New Revision: 148741

URL: http://llvm.org/viewvc/llvm-project?rev=148741&view=rev
Log:
start the implementation of a new ConstantDataVector and ConstantDataArray
classes, per PR1324.  Not all of their helper functions are implemented,
nothing creates them, and the rest of the compiler doesn't handle them yet.

Modified:
    llvm/trunk/include/llvm/Constants.h
    llvm/trunk/include/llvm/Value.h
    llvm/trunk/lib/VMCore/Constants.cpp
    llvm/trunk/lib/VMCore/LLVMContextImpl.cpp
    llvm/trunk/lib/VMCore/LLVMContextImpl.h

Modified: llvm/trunk/include/llvm/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=148741&r1=148740&r2=148741&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Constants.h (original)
+++ llvm/trunk/include/llvm/Constants.h Mon Jan 23 16:57:10 2012
@@ -34,6 +34,7 @@
 class StructType;
 class PointerType;
 class VectorType;
+class SequentialType;
 
 template<class ConstantClass, class TypeClass, class ValType>
 struct ConstantCreator;
@@ -298,7 +299,6 @@
 /// ConstantAggregateZero - All zero aggregate value
 ///
 class ConstantAggregateZero : public Constant {
-  friend struct ConstantCreator<ConstantAggregateZero, Type, char>;
   void *operator new(size_t, unsigned);                      // DO NOT IMPLEMENT
   ConstantAggregateZero(const ConstantAggregateZero &);      // DO NOT IMPLEMENT
 protected:
@@ -503,7 +503,6 @@
 /// ConstantPointerNull - a constant pointer value that points to null
 ///
 class ConstantPointerNull : public Constant {
-  friend struct ConstantCreator<ConstantPointerNull, PointerType, char>;
   void *operator new(size_t, unsigned);                  // DO NOT IMPLEMENT
   ConstantPointerNull(const ConstantPointerNull &);      // DO NOT IMPLEMENT
 protected:
@@ -535,6 +534,166 @@
     return V->getValueID() == ConstantPointerNullVal;
   }
 };
+  
+//===----------------------------------------------------------------------===//
+/// ConstantDataSequential - A vector or array of data that contains no
+/// relocations, and whose element type is a simple 1/2/4/8-byte integer or
+/// float/double.  This is the common base class of ConstantDataArray and
+/// ConstantDataVector.
+///
+class ConstantDataSequential : public Constant {
+  friend class LLVMContextImpl;
+  /// DataElements - A pointer to the bytes underlying this constant (which is
+  /// owned by the uniquing StringMap).
+  const char *DataElements;
+  
+  /// Next - This forms a link list of ConstantDataSequential nodes that have
+  /// the same value but different type.  For example, 0,0,0,1 could be a 4
+  /// element array of i8, or a 1-element array of i32.  They'll both end up in
+  /// the same StringMap bucket, linked up.
+  ConstantDataSequential *Next;
+  void *operator new(size_t, unsigned);                      // DO NOT IMPLEMENT
+  ConstantDataSequential(const ConstantDataSequential &);    // DO NOT IMPLEMENT
+protected:
+  explicit ConstantDataSequential(Type *ty, ValueTy VT, const char *Data)
+    : Constant(ty, VT, 0, 0), DataElements(Data) {}
+  ~ConstantDataSequential() { delete Next; }
+  
+  static Constant *getImpl(StringRef Bytes, Type *Ty);
+
+protected:
+  // allocate space for exactly zero operands.
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+  
+  virtual void destroyConstant();
+
+  /// getElementAsInteger - If this is a sequential container of integers (of
+  /// any size), return the specified element in the low bits of a uint64_t.
+  uint64_t getElementAsInteger(unsigned i) const;
+
+  /// getElementAsAPFloat - If this is a sequential container of floating point
+  /// type, return the specified element as an APFloat.
+  APFloat getElementAsAPFloat(unsigned i) const;
+
+  /// getElementAsFloat - If this is an sequential container of floats, return
+  /// the specified element as a float.
+  float getElementAsFloat(unsigned i) const;
+  
+  /// getElementAsDouble - If this is an sequential container of doubles, return
+  /// the specified element as a float.
+  double getElementAsDouble(unsigned i) const;
+  
+  /// getElementAsConstant - Return a Constant for a specified index's element.
+  /// Note that this has to compute a new constant to return, so it isn't as
+  /// efficient as getElementAsInteger/Float/Double.
+  Constant *getElementAsConstant(unsigned i) const;
+  
+  /// getType - Specialize the getType() method to always return a
+  /// SequentialType, which reduces the amount of casting needed in parts of the
+  /// compiler.
+  inline SequentialType *getType() const {
+    return reinterpret_cast<SequentialType*>(Value::getType());
+  }
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  ///
+  static bool classof(const ConstantDataSequential *) { return true; }
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantDataArrayVal ||
+           V->getValueID() == ConstantDataVectorVal;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantDataArray - An array of data that contains no relocations, and whose
+/// element type is a simple 1/2/4/8-byte integer or float/double.
+///
+class ConstantDataArray : public ConstantDataSequential {
+  void *operator new(size_t, unsigned);            // DO NOT IMPLEMENT
+  ConstantDataArray(const ConstantDataArray &);    // DO NOT IMPLEMENT
+  virtual void anchor();
+  friend class ConstantDataSequential;
+  explicit ConstantDataArray(Type *ty, const char *Data)
+    : ConstantDataSequential(ty, ConstantDataArrayVal, Data) {}
+protected:
+  // allocate space for exactly zero operands.
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+  
+  /// get() constructors - Return a constant with array type with an element
+  /// count and element type matching the ArrayRef passed in.  Note that this
+  /// can return a ConstantAggregateZero object.
+  static Constant *get(ArrayRef<uint8_t> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<uint16_t> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<uint32_t> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<uint64_t> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<float> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<double> Elts, LLVMContext &Context);
+  
+  /// getType - Specialize the getType() method to always return an ArrayType,
+  /// which reduces the amount of casting needed in parts of the compiler.
+  ///
+  inline ArrayType *getType() const {
+    return reinterpret_cast<ArrayType*>(Value::getType());
+  }
+  
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  ///
+  static bool classof(const ConstantDataArray *) { return true; }
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantDataArrayVal;
+  }
+};
+  
+//===----------------------------------------------------------------------===//
+/// ConstantDataVector - A vector of data that contains no relocations, and
+/// whose element type is a simple 1/2/4/8-byte integer or float/double.
+///
+class ConstantDataVector : public ConstantDataSequential {
+  void *operator new(size_t, unsigned);              // DO NOT IMPLEMENT
+  ConstantDataVector(const ConstantDataVector &);    // DO NOT IMPLEMENT
+  virtual void anchor();
+  friend class ConstantDataSequential;
+  explicit ConstantDataVector(Type *ty, const char *Data)
+  : ConstantDataSequential(ty, ConstantDataVectorVal, Data) {}
+protected:
+  // allocate space for exactly zero operands.
+  void *operator new(size_t s) {
+    return User::operator new(s, 0);
+  }
+public:
+  
+  /// get() constructors - Return a constant with vector type with an element
+  /// count and element type matching the ArrayRef passed in.  Note that this
+  /// can return a ConstantAggregateZero object.
+  static Constant *get(ArrayRef<uint8_t> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<uint16_t> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<uint32_t> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<uint64_t> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<float> Elts, LLVMContext &Context);
+  static Constant *get(ArrayRef<double> Elts, LLVMContext &Context);
+  
+  /// getType - Specialize the getType() method to always return a VectorType,
+  /// which reduces the amount of casting needed in parts of the compiler.
+  ///
+  inline VectorType *getType() const {
+    return reinterpret_cast<VectorType*>(Value::getType());
+  }
+  
+  /// Methods for support type inquiry through isa, cast, and dyn_cast:
+  ///
+  static bool classof(const ConstantDataVector *) { return true; }
+  static bool classof(const Value *V) {
+    return V->getValueID() == ConstantDataVectorVal;
+  }
+};
+
+
 
 /// BlockAddress - The address of a basic block.
 ///
@@ -893,7 +1052,6 @@
 /// LangRef.html#undefvalues for details.
 ///
 class UndefValue : public Constant {
-  friend struct ConstantCreator<UndefValue, Type, char>;
   void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
   UndefValue(const UndefValue &);      // DO NOT IMPLEMENT
 protected:

Modified: llvm/trunk/include/llvm/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=148741&r1=148740&r2=148741&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Value.h (original)
+++ llvm/trunk/include/llvm/Value.h Mon Jan 23 16:57:10 2012
@@ -193,6 +193,8 @@
     BlockAddressVal,          // This is an instance of BlockAddress
     ConstantExprVal,          // This is an instance of ConstantExpr
     ConstantAggregateZeroVal, // This is an instance of ConstantAggregateZero
+    ConstantDataArrayVal,     // This is an instance of ConstantDataArray
+    ConstantDataVectorVal,    // This is an instance of ConstantDataVector
     ConstantIntVal,           // This is an instance of ConstantInt
     ConstantFPVal,            // This is an instance of ConstantFP
     ConstantArrayVal,         // This is an instance of ConstantArray

Modified: llvm/trunk/lib/VMCore/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=148741&r1=148740&r2=148741&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Constants.cpp (original)
+++ llvm/trunk/lib/VMCore/Constants.cpp Mon Jan 23 16:57:10 2012
@@ -1913,6 +1913,154 @@
     OperandList[i+1] = IdxList[i];
 }
 
+//===----------------------------------------------------------------------===//
+//                       ConstantData* implementations
+
+void ConstantDataArray::anchor() {}
+void ConstantDataVector::anchor() {}
+
+/// isAllZeros - return true if the array is empty or all zeros.
+static bool isAllZeros(StringRef Arr) {
+  for (StringRef::iterator I = Arr.begin(), E = Arr.end(); I != E; ++I)
+    if (*I != 0)
+      return false;
+  return true;
+}
+/// getImpl - This is the underlying implementation of all of the
+/// ConstantDataSequential::get methods.  They all thunk down to here, providing
+/// the correct element type.  We take the bytes in as an StringRef because
+/// we *want* an underlying "char*" to avoid TBAA type punning violations.
+Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) {
+  // If the elements are all zero, return a CAZ, which is more dense.
+  if (isAllZeros(Elements))
+    return ConstantAggregateZero::get(Ty);
+
+  // Do a lookup to see if we have already formed one of these.
+  StringMap<ConstantDataSequential*>::MapEntryTy &Slot =
+    Ty->getContext().pImpl->CDSConstants.GetOrCreateValue(Elements);
+  
+  // The bucket can point to a linked list of different CDS's that have the same
+  // body but different types.  For example, 0,0,0,1 could be a 4 element array
+  // of i8, or a 1-element array of i32.  They'll both end up in the same
+  /// StringMap bucket, linked up by their Next pointers.  Walk the list.
+  ConstantDataSequential **Entry = &Slot.getValue();
+  for (ConstantDataSequential *Node = *Entry; Node != 0;
+       Entry = &Node->Next, Node = *Entry)
+    if (Node->getType() == Ty)
+      return Node;
+  
+  // Okay, we didn't get a hit.  Create a node of the right class, link it in,
+  // and return it.
+  if (isa<ArrayType>(Ty))
+    return *Entry = new ConstantDataArray(Ty, Slot.getKeyData());
+
+  assert(isa<VectorType>(Ty));
+  return *Entry = new ConstantDataVector(Ty, Slot.getKeyData());
+}
+
+void ConstantDataSequential::destroyConstant() {
+  uint64_t ByteSize =
+    getType()->getElementType()->getPrimitiveSizeInBits()/8 *
+    getType()->getElementType()->getNumElements();
+  
+  // Remove the constant from the StringMap.
+  StringMap<ConstantDataSequential*> &CDSConstants = 
+    getType()->getContext().pImpl->CDSConstants;
+  
+  StringMap<ConstantDataSequential*>::iterator Slot =
+    CDSConstants.find(StringRef(DataElements, ByteSize));
+
+  assert(Slot != CDSConstants.end() && "CDS not found in uniquing table");
+
+  ConstantDataSequential **Entry = &Slot->getValue();
+
+  // Remove the entry from the hash table.
+  if ((*Entry)->Next == 0) {
+    // If there is only one value in the bucket (common case) it must be this
+    // entry, and removing the entry should remove the bucket completely.
+    assert((*Entry) == this && "Hash mismatch in ConstantDataSequential");
+    getContext().pImpl->CDSConstants.erase(Slot);
+  } else {
+    // Otherwise, there are multiple entries linked off the bucket, unlink the 
+    // node we care about but keep the bucket around.
+    for (ConstantDataSequential *Node = *Entry; ;
+         Entry = &Node->Next, Node = *Entry) {
+      assert(Node && "Didn't find entry in its uniquing hash table!");
+      // If we found our entry, unlink it from the list and we're done.
+      if (Node == this) {
+        *Entry = Node->Next;
+        break;
+      }
+    }
+  }
+  
+  // If we were part of a list, make sure that we don't delete the list that is
+  // still owned by the uniquing map.
+  Next = 0;
+  
+  // Finally, actually delete it.
+  destroyConstantImpl();
+}
+
+/// get() constructors - Return a constant with array type with an element
+/// count and element type matching the ArrayRef passed in.  Note that this
+/// can return a ConstantAggregateZero object.
+Constant *ConstantDataArray::get(ArrayRef<uint8_t> Elts, LLVMContext &Context) {
+  Type *Ty = ArrayType::get(Type::getInt8Ty(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*1), Ty);
+}
+Constant *ConstantDataArray::get(ArrayRef<uint16_t> Elts, LLVMContext &Context){
+  Type *Ty = ArrayType::get(Type::getInt16Ty(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*2), Ty);
+}
+Constant *ConstantDataArray::get(ArrayRef<uint32_t> Elts, LLVMContext &Context){
+  Type *Ty = ArrayType::get(Type::getInt32Ty(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty);
+}
+Constant *ConstantDataArray::get(ArrayRef<uint64_t> Elts, LLVMContext &Context){
+  Type *Ty = ArrayType::get(Type::getInt64Ty(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
+}
+Constant *ConstantDataArray::get(ArrayRef<float> Elts, LLVMContext &Context) {
+  Type *Ty = ArrayType::get(Type::getFloatTy(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty);
+}
+Constant *ConstantDataArray::get(ArrayRef<double> Elts, LLVMContext &Context) {
+  Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
+}
+
+
+/// get() constructors - Return a constant with vector type with an element
+/// count and element type matching the ArrayRef passed in.  Note that this
+/// can return a ConstantAggregateZero object.
+Constant *ConstantDataVector::get(ArrayRef<uint8_t> Elts, LLVMContext &Context) {
+  Type *Ty = VectorType::get(Type::getInt8Ty(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*1), Ty);
+}
+Constant *ConstantDataVector::get(ArrayRef<uint16_t> Elts, LLVMContext &Context){
+  Type *Ty = VectorType::get(Type::getInt16Ty(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*2), Ty);
+}
+Constant *ConstantDataVector::get(ArrayRef<uint32_t> Elts, LLVMContext &Context){
+  Type *Ty = VectorType::get(Type::getInt32Ty(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty);
+}
+Constant *ConstantDataVector::get(ArrayRef<uint64_t> Elts, LLVMContext &Context){
+  Type *Ty = VectorType::get(Type::getInt64Ty(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
+}
+Constant *ConstantDataVector::get(ArrayRef<float> Elts, LLVMContext &Context) {
+  Type *Ty = VectorType::get(Type::getFloatTy(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty);
+}
+Constant *ConstantDataVector::get(ArrayRef<double> Elts, LLVMContext &Context) {
+  Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size());
+  return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
+}
+
+
+
 
 //===----------------------------------------------------------------------===//
 //                replaceUsesOfWithOnConstant implementations

Modified: llvm/trunk/lib/VMCore/LLVMContextImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContextImpl.cpp?rev=148741&r1=148740&r2=148741&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/LLVMContextImpl.cpp (original)
+++ llvm/trunk/lib/VMCore/LLVMContextImpl.cpp Mon Jan 23 16:57:10 2012
@@ -79,6 +79,11 @@
   DeleteContainerSeconds(IntConstants);
   DeleteContainerSeconds(FPConstants);
   
+  for (StringMap<ConstantDataSequential*>::iterator I = CDSConstants.begin(),
+       E = CDSConstants.end(); I != E; ++I)
+    delete I->second;
+  CDSConstants.clear();
+  
   // Destroy MDNodes.  ~MDNode can move and remove nodes between the MDNodeSet
   // and the NonUniquedMDNodes sets, so copy the values out first.
   SmallVector<MDNode*, 8> MDNodes;

Modified: llvm/trunk/lib/VMCore/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContextImpl.h?rev=148741&r1=148740&r2=148741&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/VMCore/LLVMContextImpl.h Mon Jan 23 16:57:10 2012
@@ -156,6 +156,9 @@
 
   DenseMap<Type*, UndefValue*> UVConstants;
   
+  StringMap<ConstantDataSequential*> CDSConstants;
+
+  
   DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
   ConstantUniqueMap<ExprMapKeyType, const ExprMapKeyType&, Type, ConstantExpr>
     ExprConstants;





More information about the llvm-commits mailing list