From 27dd9cf5d1ec831a1cd0766580e6d1177a9800a3 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 23 Jan 2012 22:57:10 +0000 Subject: start the implementation of a new ConstantDataVector and ConstantDataArray classes, per PR1324. Not all of their helper functions are implemented, nothing creates them, and the rest of the compiler doesn't handle them yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148741 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/VMCore/Constants.cpp | 148 +++++++++++++++++++++++++++++++++++++++++ lib/VMCore/LLVMContextImpl.cpp | 5 ++ lib/VMCore/LLVMContextImpl.h | 3 + 3 files changed, 156 insertions(+) (limited to 'lib/VMCore') diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index e9b433b..3b52a7c 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -1913,6 +1913,154 @@ GetElementPtrConstantExpr(Constant *C, const std::vector &IdxList, OperandList[i+1] = IdxList[i]; } +//===----------------------------------------------------------------------===// +// ConstantData* implementations + +void ConstantDataArray::anchor() {} +void ConstantDataVector::anchor() {} + +/// 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) + if (*I != 0) + return false; + return true; +} +/// getImpl - This is the underlying implementation of all of the +/// ConstantDataSequential::get methods. They all thunk down to here, providing +/// 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) { + // If the elements are all zero, return a CAZ, which is more dense. + if (isAllZeros(Elements)) + return ConstantAggregateZero::get(Ty); + + // Do a lookup to see if we have already formed one of these. + StringMap::MapEntryTy &Slot = + Ty->getContext().pImpl->CDSConstants.GetOrCreateValue(Elements); + + // The bucket can point to a linked list of different CDS's that have the same + // body but different types. For example, 0,0,0,1 could be a 4 element array + // of i8, or a 1-element array of i32. They'll both end up in the same + /// StringMap bucket, linked up by their Next pointers. Walk the list. + ConstantDataSequential **Entry = &Slot.getValue(); + for (ConstantDataSequential *Node = *Entry; Node != 0; + Entry = &Node->Next, Node = *Entry) + if (Node->getType() == Ty) + return Node; + + // Okay, we didn't get a hit. Create a node of the right class, link it in, + // and return it. + if (isa(Ty)) + return *Entry = new ConstantDataArray(Ty, Slot.getKeyData()); + + assert(isa(Ty)); + return *Entry = new ConstantDataVector(Ty, Slot.getKeyData()); +} + +void ConstantDataSequential::destroyConstant() { + uint64_t ByteSize = + getType()->getElementType()->getPrimitiveSizeInBits()/8 * + getType()->getElementType()->getNumElements(); + + // Remove the constant from the StringMap. + StringMap &CDSConstants = + getType()->getContext().pImpl->CDSConstants; + + StringMap::iterator Slot = + CDSConstants.find(StringRef(DataElements, ByteSize)); + + assert(Slot != CDSConstants.end() && "CDS not found in uniquing table"); + + ConstantDataSequential **Entry = &Slot->getValue(); + + // Remove the entry from the hash table. + if ((*Entry)->Next == 0) { + // If there is only one value in the bucket (common case) it must be this + // entry, and removing the entry should remove the bucket completely. + assert((*Entry) == this && "Hash mismatch in ConstantDataSequential"); + getContext().pImpl->CDSConstants.erase(Slot); + } else { + // Otherwise, there are multiple entries linked off the bucket, unlink the + // node we care about but keep the bucket around. + for (ConstantDataSequential *Node = *Entry; ; + Entry = &Node->Next, Node = *Entry) { + assert(Node && "Didn't find entry in its uniquing hash table!"); + // If we found our entry, unlink it from the list and we're done. + if (Node == this) { + *Entry = Node->Next; + break; + } + } + } + + // If we were part of a list, make sure that we don't delete the list that is + // still owned by the uniquing map. + Next = 0; + + // Finally, actually delete it. + destroyConstantImpl(); +} + +/// get() constructors - Return a constant with array type with an element +/// count and element type matching the ArrayRef passed in. Note that this +/// can return a ConstantAggregateZero object. +Constant *ConstantDataArray::get(ArrayRef Elts, LLVMContext &Context) { + Type *Ty = ArrayType::get(Type::getInt8Ty(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*1), Ty); +} +Constant *ConstantDataArray::get(ArrayRef Elts, LLVMContext &Context){ + Type *Ty = ArrayType::get(Type::getInt16Ty(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*2), Ty); +} +Constant *ConstantDataArray::get(ArrayRef Elts, LLVMContext &Context){ + Type *Ty = ArrayType::get(Type::getInt32Ty(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty); +} +Constant *ConstantDataArray::get(ArrayRef Elts, LLVMContext &Context){ + Type *Ty = ArrayType::get(Type::getInt64Ty(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty); +} +Constant *ConstantDataArray::get(ArrayRef Elts, LLVMContext &Context) { + Type *Ty = ArrayType::get(Type::getFloatTy(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty); +} +Constant *ConstantDataArray::get(ArrayRef Elts, LLVMContext &Context) { + Type *Ty = ArrayType::get(Type::getDoubleTy(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty); +} + + +/// get() constructors - Return a constant with vector type with an element +/// count and element type matching the ArrayRef passed in. Note that this +/// can return a ConstantAggregateZero object. +Constant *ConstantDataVector::get(ArrayRef Elts, LLVMContext &Context) { + Type *Ty = VectorType::get(Type::getInt8Ty(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*1), Ty); +} +Constant *ConstantDataVector::get(ArrayRef Elts, LLVMContext &Context){ + Type *Ty = VectorType::get(Type::getInt16Ty(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*2), Ty); +} +Constant *ConstantDataVector::get(ArrayRef Elts, LLVMContext &Context){ + Type *Ty = VectorType::get(Type::getInt32Ty(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty); +} +Constant *ConstantDataVector::get(ArrayRef Elts, LLVMContext &Context){ + Type *Ty = VectorType::get(Type::getInt64Ty(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty); +} +Constant *ConstantDataVector::get(ArrayRef Elts, LLVMContext &Context) { + Type *Ty = VectorType::get(Type::getFloatTy(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*4), Ty); +} +Constant *ConstantDataVector::get(ArrayRef Elts, LLVMContext &Context) { + Type *Ty = VectorType::get(Type::getDoubleTy(Context), Elts.size()); + return getImpl(StringRef((char*)Elts.data(), Elts.size()*8), Ty); +} + + + //===----------------------------------------------------------------------===// // replaceUsesOfWithOnConstant implementations diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index 2eaebac..15c5c24 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -79,6 +79,11 @@ LLVMContextImpl::~LLVMContextImpl() { DeleteContainerSeconds(IntConstants); DeleteContainerSeconds(FPConstants); + for (StringMap::iterator I = CDSConstants.begin(), + E = CDSConstants.end(); I != E; ++I) + delete I->second; + CDSConstants.clear(); + // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // and the NonUniquedMDNodes sets, so copy the values out first. SmallVector MDNodes; diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index f8abdf1..ca37ffa 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -156,6 +156,9 @@ public: DenseMap UVConstants; + StringMap CDSConstants; + + DenseMap , BlockAddress*> BlockAddresses; ConstantUniqueMap ExprConstants; -- cgit v1.1