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

Chris Lattner sabre at nondot.org
Mon Jan 23 20:43:41 PST 2012


Author: lattner
Date: Mon Jan 23 22:43:41 2012
New Revision: 148778

URL: http://llvm.org/viewvc/llvm-project?rev=148778&view=rev
Log:
implement the ConstantDataSequential accessor methods.

No need for 'getOperand' :)

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

Modified: llvm/trunk/include/llvm/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=148778&r1=148777&r2=148778&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Constants.h (original)
+++ llvm/trunk/include/llvm/Constants.h Mon Jan 23 22:43:41 2012
@@ -597,6 +597,10 @@
   inline SequentialType *getType() const {
     return reinterpret_cast<SequentialType*>(Value::getType());
   }
+  
+  /// getElementType - Return the element type of the array/vector.
+  Type *getElementType() const;
+
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
   ///
@@ -605,6 +609,9 @@
     return V->getValueID() == ConstantDataArrayVal ||
            V->getValueID() == ConstantDataVectorVal;
   }
+private:
+  uint64_t getElementByteSize() const;
+  const char *getElementPointer(unsigned Elt) const;
 };
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/VMCore/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=148778&r1=148777&r2=148778&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Constants.cpp (original)
+++ llvm/trunk/lib/VMCore/Constants.cpp Mon Jan 23 22:43:41 2012
@@ -1919,6 +1919,40 @@
 void ConstantDataArray::anchor() {}
 void ConstantDataVector::anchor() {}
 
+/// getElementType - Return the element type of the array/vector.
+Type *ConstantDataSequential::getElementType() const {
+  return getType()->getElementType();
+}
+
+/// isElementTypeConstantDataCompatible - Return true if this type is valid for
+/// a ConstantDataSequential.  This is i8/i16/i32/i64/float/double.
+static bool isElementTypeConstantDataCompatible(const Type *Ty) {
+  if (Ty->isFloatTy() || Ty->isDoubleTy()) return true;
+  if (const IntegerType *IT = dyn_cast<IntegerType>(Ty)) {
+    switch (IT->getBitWidth()) {
+    case 8:
+    case 16:
+    case 32:
+    case 64:
+      return true;
+    default: break;
+    }
+  }
+  return false;
+}
+
+/// getElementByteSize - Return the size in bytes of the elements in the data.
+uint64_t ConstantDataSequential::getElementByteSize() const {
+  return getElementType()->getPrimitiveSizeInBits()/8;
+}
+
+/// getElementPointer - Return the start of the specified element.
+const char *ConstantDataSequential::getElementPointer(unsigned Elt) const {
+  assert(Elt < getElementType()->getNumElements() && "Invalid Elt");
+  return DataElements+Elt*getElementByteSize();
+}
+
+
 /// 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)
@@ -1931,6 +1965,8 @@
 /// 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) {
+  assert(isElementTypeConstantDataCompatible(cast<SequentialType>(Ty)->
+                                             getElementType()));
   // If the elements are all zero, return a CAZ, which is more dense.
   if (isAllZeros(Elements))
     return ConstantAggregateZero::get(Ty);
@@ -1959,9 +1995,7 @@
 }
 
 void ConstantDataSequential::destroyConstant() {
-  uint64_t ByteSize =
-    getType()->getElementType()->getPrimitiveSizeInBits()/8 *
-    getType()->getElementType()->getNumElements();
+  uint64_t ByteSize = getElementByteSize() * getElementType()->getNumElements();
   
   // Remove the constant from the StringMap.
   StringMap<ConstantDataSequential*> &CDSConstants = 
@@ -2059,6 +2093,62 @@
   return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty);
 }
 
+/// 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 ConstantDataSequential::getElementAsInteger(unsigned Elt) const {
+  assert(isa<IntegerType>(getElementType()) &&
+         "Accessor can only be used when element is an integer");
+  const char *EltPtr = getElementPointer(Elt);
+  
+  // The data is stored in host byte order, make sure to cast back to the right
+  // type to load with the right endianness.
+  switch (cast<IntegerType>(getElementType())->getBitWidth()) {
+  default: assert(0 && "Invalid bitwidth for CDS");
+  case 8:  return *(uint8_t*)EltPtr;
+  case 16: return *(uint16_t*)EltPtr;
+  case 32: return *(uint32_t*)EltPtr;
+  case 64: return *(uint64_t*)EltPtr;
+  }
+}
+
+/// getElementAsAPFloat - If this is a sequential container of floating point
+/// type, return the specified element as an APFloat.
+APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
+  const char *EltPtr = getElementPointer(Elt);
+
+  switch (getElementType()->getTypeID()) {
+  default: assert("Accessor can only be used when element is float/double!");
+  case Type::FloatTyID: return APFloat(*(float*)EltPtr);
+  case Type::DoubleTyID: return APFloat(*(double*)EltPtr);
+  }
+}
+
+/// getElementAsFloat - If this is an sequential container of floats, return
+/// the specified element as a float.
+float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {
+  assert(getElementType()->isFloatTy() &&
+         "Accessor can only be used when element is a 'float'");
+  return *(float*)getElementPointer(Elt);
+}
+
+/// getElementAsDouble - If this is an sequential container of doubles, return
+/// the specified element as a float.
+double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
+  assert(getElementType()->isDoubleTy() &&
+         "Accessor can only be used when element is a 'float'");
+  return *(double*)getElementPointer(Elt);
+}
+
+/// 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 *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {
+  if (getElementType()->isFloatTy() || getElementType()->isDoubleTy())
+    return ConstantFP::get(getContext(), getElementAsAPFloat(Elt));
+  
+  return ConstantInt::get(getElementType(), getElementAsInteger(Elt));
+}
+
 
 
 





More information about the llvm-commits mailing list