summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2012-01-24 04:43:41 +0000
committerChris Lattner <sabre@nondot.org>2012-01-24 04:43:41 +0000
commit45bb5c5333fba7e9909cca178d785bf2c1d2b0c1 (patch)
treefa1e29413e273f31a56acfe03cfc080aa501da08
parentdfc8e470b6fcccdba23d5dc4bc5d4e47db7e6544 (diff)
downloadllvm-45bb5c5333fba7e9909cca178d785bf2c1d2b0c1.tar.gz
llvm-45bb5c5333fba7e9909cca178d785bf2c1d2b0c1.tar.bz2
llvm-45bb5c5333fba7e9909cca178d785bf2c1d2b0c1.tar.xz
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
-rw-r--r--include/llvm/Constants.h7
-rw-r--r--lib/VMCore/Constants.cpp96
2 files changed, 100 insertions, 3 deletions
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index 022ac2d393..1fc3308494 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -597,6 +597,10 @@ public:
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 @@ public:
return V->getValueID() == ConstantDataArrayVal ||
V->getValueID() == ConstantDataVectorVal;
}
+private:
+ uint64_t getElementByteSize() const;
+ const char *getElementPointer(unsigned Elt) const;
};
//===----------------------------------------------------------------------===//
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 3b52a7cdeb..86087e4efb 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));
+}
+