diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-01 04:51:17 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-02-01 04:51:17 +0000 |
commit | 91766fe066efe6e0969ba805a2e3726a70ed34a3 (patch) | |
tree | 4341aed84ba24607ccb4c8426dfd695b2e484abb /lib/VMCore/Constants.cpp | |
parent | de5e5ec3045a73a06b1054417f9ac6c02929e9ce (diff) |
Revert Chris' commits up to r149348 that started causing VMCoreTests unit test to fail.
These are:
r149348
r149351
r149352
r149354
r149356
r149357
r149361
r149362
r149364
r149365
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149470 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Constants.cpp')
-rw-r--r-- | lib/VMCore/Constants.cpp | 196 |
1 files changed, 105 insertions, 91 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 7d423c04a6..f7884c6862 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -176,7 +176,7 @@ Constant *Constant::getAggregateElement(unsigned Elt) const { return UV->getElementValue(Elt); if (const ConstantDataSequential *CDS =dyn_cast<ConstantDataSequential>(this)) - return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) : 0; + return CDS->getElementAsConstant(Elt); return 0; } @@ -666,13 +666,6 @@ UndefValue *UndefValue::getElementValue(unsigned Idx) const { // ConstantXXX Classes //===----------------------------------------------------------------------===// -template <typename ItTy, typename EltTy> -static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) { - for (; Start != End; ++Start) - if (*Start != Elt) - return false; - return true; -} ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V) : Constant(T, ConstantArrayVal, @@ -687,97 +680,54 @@ ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V) } Constant *ConstantArray::get(ArrayType *Ty, ArrayRef<Constant*> V) { - // Empty arrays are canonicalized to ConstantAggregateZero. - if (V.empty()) - return ConstantAggregateZero::get(Ty); - for (unsigned i = 0, e = V.size(); i != e; ++i) { assert(V[i]->getType() == Ty->getElementType() && "Wrong type in array element initializer"); } LLVMContextImpl *pImpl = Ty->getContext().pImpl; - - // If this is an all-zero array, return a ConstantAggregateZero object. If - // all undef, return an UndefValue, if "all simple", then return a - // ConstantDataArray. - Constant *C = V[0]; - if (isa<UndefValue>(C) && rangeOnlyContains(V.begin(), V.end(), C)) - return UndefValue::get(Ty); + // If this is an all-zero array, return a ConstantAggregateZero object + bool isAllZero = true; + bool isUndef = false; + if (!V.empty()) { + Constant *C = V[0]; + isAllZero = C->isNullValue(); + isUndef = isa<UndefValue>(C); + + if (isAllZero || isUndef) + for (unsigned i = 1, e = V.size(); i != e; ++i) + if (V[i] != C) { + isAllZero = false; + isUndef = false; + break; + } + } - if (C->isNullValue() && rangeOnlyContains(V.begin(), V.end(), C)) + if (isAllZero) return ConstantAggregateZero::get(Ty); + if (isUndef) + return UndefValue::get(Ty); + return pImpl->ArrayConstants.getOrCreate(Ty, V); +} - // Check to see if all of the elements are ConstantFP or ConstantInt and if - // the element type is compatible with ConstantDataVector. If so, use it. - if (ConstantDataSequential::isElementTypeCompatible(C->getType())) { - // We speculatively build the elements here even if it turns out that there - // is a constantexpr or something else weird in the array, since it is so - // uncommon for that to happen. - if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) { - if (CI->getType()->isIntegerTy(8)) { - SmallVector<uint8_t, 16> Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(16)) { - SmallVector<uint16_t, 16> Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(32)) { - SmallVector<uint32_t, 16> Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } else if (CI->getType()->isIntegerTy(64)) { - SmallVector<uint64_t, 16> Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantInt *CI = dyn_cast<ConstantInt>(V[i])) - Elts.push_back(CI->getZExtValue()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } - } - - if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { - if (CFP->getType()->isFloatTy()) { - SmallVector<float, 16> Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i])) - Elts.push_back(CFP->getValueAPF().convertToFloat()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } else if (CFP->getType()->isDoubleTy()) { - SmallVector<double, 16> Elts; - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (ConstantFP *CFP = dyn_cast<ConstantFP>(V[i])) - Elts.push_back(CFP->getValueAPF().convertToDouble()); - else - break; - if (Elts.size() == V.size()) - return ConstantDataArray::get(C->getContext(), Elts); - } - } - } +/// ConstantArray::get(const string&) - Return an array that is initialized to +/// contain the specified string. If length is zero then a null terminator is +/// added to the specified string so that it may be used in a natural way. +/// Otherwise, the length parameter specifies how much of the string to use +/// and it won't be null terminated. +/// +Constant *ConstantArray::get(LLVMContext &Context, StringRef Str, + bool AddNull) { + SmallVector<Constant*, 8> ElementVals; + ElementVals.reserve(Str.size() + size_t(AddNull)); + for (unsigned i = 0; i < Str.size(); ++i) + ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), Str[i])); - // Otherwise, we really do want to create a ConstantArray. - return pImpl->ArrayConstants.getOrCreate(Ty, V); + // Add a null terminator to the string... + if (AddNull) + ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0)); + + ArrayType *ATy = ArrayType::get(Type::getInt8Ty(Context), ElementVals.size()); + return get(ATy, ElementVals); } /// getTypeForElements - Return an anonymous struct type to use for a constant @@ -889,7 +839,8 @@ Constant *ConstantVector::get(ArrayRef<Constant*> V) { // Check to see if all of the elements are ConstantFP or ConstantInt and if // the element type is compatible with ConstantDataVector. If so, use it. - if (ConstantDataSequential::isElementTypeCompatible(C->getType())) { + if (ConstantDataSequential::isElementTypeCompatible(C->getType()) && + (isa<ConstantFP>(C) || isa<ConstantInt>(C))) { // We speculatively build the elements here even if it turns out that there // is a constantexpr or something else weird in the array, since it is so // uncommon for that to happen. @@ -1195,6 +1146,69 @@ void ConstantArray::destroyConstant() { destroyConstantImpl(); } +/// isString - This method returns true if the array is an array of i8, and +/// if the elements of the array are all ConstantInt's. +bool ConstantArray::isString() const { + // Check the element type for i8... + if (!getType()->getElementType()->isIntegerTy(8)) + return false; + // Check the elements to make sure they are all integers, not constant + // expressions. + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (!isa<ConstantInt>(getOperand(i))) + return false; + return true; +} + +/// isCString - This method returns true if the array is a string (see +/// isString) and it ends in a null byte \\0 and does not contains any other +/// null bytes except its terminator. +bool ConstantArray::isCString() const { + // Check the element type for i8... + if (!getType()->getElementType()->isIntegerTy(8)) + return false; + + // Last element must be a null. + if (!getOperand(getNumOperands()-1)->isNullValue()) + return false; + // Other elements must be non-null integers. + for (unsigned i = 0, e = getNumOperands()-1; i != e; ++i) { + if (!isa<ConstantInt>(getOperand(i))) + return false; + if (getOperand(i)->isNullValue()) + return false; + } + return true; +} + + +/// convertToString - Helper function for getAsString() and getAsCString(). +static std::string convertToString(const User *U, unsigned len) { + std::string Result; + Result.reserve(len); + for (unsigned i = 0; i != len; ++i) + Result.push_back((char)cast<ConstantInt>(U->getOperand(i))->getZExtValue()); + return Result; +} + +/// getAsString - If this array is isString(), then this method converts the +/// array to an std::string and returns it. Otherwise, it asserts out. +/// +std::string ConstantArray::getAsString() const { + assert(isString() && "Not a string!"); + return convertToString(this, getNumOperands()); +} + + +/// getAsCString - If this array is isCString(), then this method converts the +/// array (without the trailing null byte) to an std::string and returns it. +/// Otherwise, it asserts out. +/// +std::string ConstantArray::getAsCString() const { + assert(isCString() && "Not a string!"); + return convertToString(this, getNumOperands() - 1); +} + //---- ConstantStruct::get() implementation... // |