diff options
author | Chris Lattner <sabre@nondot.org> | 2012-01-24 04:43:41 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2012-01-24 04:43:41 +0000 |
commit | 45bb5c5333fba7e9909cca178d785bf2c1d2b0c1 (patch) | |
tree | fa1e29413e273f31a56acfe03cfc080aa501da08 /lib/VMCore | |
parent | dfc8e470b6fcccdba23d5dc4bc5d4e47db7e6544 (diff) | |
download | external_llvm-45bb5c5333fba7e9909cca178d785bf2c1d2b0c1.zip external_llvm-45bb5c5333fba7e9909cca178d785bf2c1d2b0c1.tar.gz external_llvm-45bb5c5333fba7e9909cca178d785bf2c1d2b0c1.tar.bz2 |
implement the ConstantDataSequential accessor methods.
No need for 'getOperand' :)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148778 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/Constants.cpp | 96 |
1 files changed, 93 insertions, 3 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 3b52a7c..86087e4 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -1919,6 +1919,40 @@ GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList, 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 @@ static bool isAllZeros(StringRef Arr) { /// 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 @@ Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) { } 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 @@ Constant *ConstantDataVector::get(ArrayRef<double> Elts, LLVMContext &Context) { 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)); +} + |