[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