diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index da6fe96a772..fdcc53bc79d 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -38,7 +38,7 @@ class VectorType; template struct ConstantCreator; template -struct ConvertConstantType; +struct ConvertConstant; //===----------------------------------------------------------------------===// /// This is the shared class of boolean and integer constants. This class @@ -559,7 +559,7 @@ public: class ConstantExpr : public Constant { friend struct ConstantCreator > >; - friend struct ConvertConstantType; + friend struct ConvertConstant; protected: ConstantExpr(const Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps) diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 0844006396d..b38336b98b0 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -19,9 +19,7 @@ #include "llvm/User.h" #include "llvm/Type.h" #include "llvm/OperandTraits.h" -#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/ilist_node.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ValueHandle.h" @@ -29,6 +27,8 @@ namespace llvm { class Constant; class LLVMContext; +template +struct ConstantCreator; //===----------------------------------------------------------------------===// // MetadataBase - A base class for MDNode, MDString and NamedMDNode. @@ -103,32 +103,14 @@ public: /// MDNode - a tuple of other values. /// These contain a list of the values that represent the metadata. /// MDNode is always unnamed. -class MDNode : public MetadataBase, public FoldingSetNode { +class MDNode : public MetadataBase { MDNode(const MDNode &); // DO NOT IMPLEMENT void *operator new(size_t, unsigned); // DO NOT IMPLEMENT // getNumOperands - Make this only available for private uses. unsigned getNumOperands() { return User::getNumOperands(); } - friend class ElementVH; - // Use CallbackVH to hold MDNOde elements. - struct ElementVH : public CallbackVH { - MDNode *Parent; - ElementVH(Value *V, MDNode *P) : CallbackVH(V), Parent(P) {} - ~ElementVH() {} - - virtual void deleted() { - Parent->replaceElement(this->operator Value*(), 0); - } - - virtual void allUsesReplacedWith(Value *NV) { - Parent->replaceElement(this->operator Value*(), NV); - } - }; - // Replace each instance of F from the element list of this node with T. - void replaceElement(Value *F, Value *T); - - SmallVector Node; - + SmallVector Node; + friend struct ConstantCreator >; protected: explicit MDNode(LLVMContext &C, Value*const* Vals, unsigned NumVals); public: @@ -158,8 +140,8 @@ public: } // Element access - typedef SmallVectorImpl::const_iterator const_elem_iterator; - typedef SmallVectorImpl::iterator elem_iterator; + typedef SmallVectorImpl::const_iterator const_elem_iterator; + typedef SmallVectorImpl::iterator elem_iterator; /// elem_empty - Return true if MDNode is empty. bool elem_empty() const { return Node.empty(); } const_elem_iterator elem_begin() const { return Node.begin(); } @@ -174,10 +156,6 @@ public: return false; } - /// Profile - calculate a unique identifier for this MDNode to collapse - /// duplicates - void Profile(FoldingSetNodeID &ID) const; - virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { llvm_unreachable("This should never be called because MDNodes have no ops"); } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 37efafc9b20..fd3266140c1 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -1880,7 +1880,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, pImpl->ArrayConstants.InsertOrGetItem(Lookup, Exists); if (Exists) { - Replacement = I->second; + Replacement = cast(I->second); } else { // Okay, the new shape doesn't exist in the system yet. Instead of // creating a new constant array, inserting it, replaceallusesof'ing the @@ -1967,7 +1967,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, pImpl->StructConstants.InsertOrGetItem(Lookup, Exists); if (Exists) { - Replacement = I->second; + Replacement = cast(I->second); } else { // Okay, the new shape doesn't exist in the system yet. Instead of // creating a new constant struct, inserting it, replaceallusesof'ing the diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h index 718470aff42..f4a2cde5d0f 100644 --- a/lib/VMCore/ConstantsContext.h +++ b/lib/VMCore/ConstantsContext.h @@ -16,6 +16,7 @@ #define LLVM_CONSTANTSCONTEXT_H #include "llvm/Instructions.h" +#include "llvm/Metadata.h" #include "llvm/Operator.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -340,7 +341,7 @@ struct ConstantCreator { }; template -struct ConvertConstantType { +struct ConvertConstant { static void convert(ConstantClass *OldC, const TypeClass *NewTy) { llvm_unreachable("This type cannot be converted!"); } @@ -391,7 +392,7 @@ struct ConstantCreator { }; template<> -struct ConvertConstantType { +struct ConvertConstant { static void convert(ConstantExpr *OldC, const Type *NewTy) { Constant *New; switch (OldC->getOpcode()) { @@ -444,7 +445,14 @@ struct ConstantCreator { }; template<> -struct ConvertConstantType { +struct ConstantCreator > { + static MDNode *create(const Type* Ty, const std::vector &V) { + return new MDNode(Ty->getContext(), &V[0], V.size()); + } +}; + +template<> +struct ConvertConstant { static void convert(ConstantVector *OldC, const VectorType *NewTy) { // Make everyone now use a constant of the new type... std::vector C; @@ -458,7 +466,7 @@ struct ConvertConstantType { }; template<> -struct ConvertConstantType { +struct ConvertConstant { static void convert(ConstantAggregateZero *OldC, const Type *NewTy) { // Make everyone now use a constant of the new type... Constant *New = ConstantAggregateZero::get(NewTy); @@ -469,7 +477,7 @@ struct ConvertConstantType { }; template<> -struct ConvertConstantType { +struct ConvertConstant { static void convert(ConstantArray *OldC, const ArrayType *NewTy) { // Make everyone now use a constant of the new type... std::vector C; @@ -483,7 +491,7 @@ struct ConvertConstantType { }; template<> -struct ConvertConstantType { +struct ConvertConstant { static void convert(ConstantStruct *OldC, const StructType *NewTy) { // Make everyone now use a constant of the new type... std::vector C; @@ -506,7 +514,7 @@ struct ConstantCreator { }; template<> -struct ConvertConstantType { +struct ConvertConstant { static void convert(ConstantPointerNull *OldC, const PointerType *NewTy) { // Make everyone now use a constant of the new type... Constant *New = ConstantPointerNull::get(NewTy); @@ -525,7 +533,7 @@ struct ConstantCreator { }; template<> -struct ConvertConstantType { +struct ConvertConstant { static void convert(UndefValue *OldC, const Type *NewTy) { // Make everyone now use a constant of the new type. Constant *New = UndefValue::get(NewTy); @@ -540,8 +548,8 @@ template MapKey; - typedef std::map MapTy; - typedef std::map InverseMapTy; + typedef std::map MapTy; + typedef std::map InverseMapTy; typedef std::map AbstractTypeMapTy; private: /// Map - This is the main map from the element descriptor to the Constants. @@ -759,8 +767,7 @@ public: // leaving will remove() itself, causing the AbstractTypeMapEntry to be // eliminated eventually. do { - ConvertConstantType::convert( + ConvertConstant::convert( static_cast(I->second->second), cast(NewTy)); diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 0ed21fb754e..1803a9a6666 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #include "llvm/LLVMContext.h" -#include "llvm/Metadata.h" #include "llvm/Constants.h" #include "llvm/Instruction.h" #include "llvm/Support/ManagedStatic.h" @@ -49,10 +48,10 @@ bool LLVMContext::RemoveDeadMetadata() { bool Changed = false; while (1) { - for (FoldingSet::iterator - I = pImpl->MDNodeSet.begin(), - E = pImpl->MDNodeSet.end(); I != E; ++I) { - const MDNode *N = &(*I); + for (SmallPtrSet::iterator + I = pImpl->MDNodes.begin(), + E = pImpl->MDNodes.end(); I != E; ++I) { + const MDNode *N = cast(*I); if (N->use_empty()) DeadMDNodes.push_back(N); } diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 1ee4ad737e4..eeafeafd9ee 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -19,7 +19,6 @@ #include "LeaksContext.h" #include "TypesContext.h" #include "llvm/LLVMContext.h" -#include "llvm/Metadata.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/System/Mutex.h" @@ -107,12 +106,10 @@ public: StringMap MDStringCache; - FoldingSet MDNodeSet; - ValueMap AggZeroConstants; SmallPtrSet MDNodes; - + typedef ValueMap, ArrayType, ConstantArray, true /*largekey*/> ArrayConstantsTy; ArrayConstantsTy ArrayConstants; @@ -202,6 +199,7 @@ public: ArrayConstants.freeConstants(); StructConstants.freeConstants(); VectorConstants.freeConstants(); + AggZeroConstants.freeConstants(); NullPtrConstants.freeConstants(); UndefValueConstants.freeConstants(); diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index bf845eb5422..bb8021485f6 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -72,37 +72,18 @@ MDNode::MDNode(LLVMContext &C, Value*const* Vals, unsigned NumVals) // Only record metadata uses. if (MetadataBase *MB = dyn_cast_or_null(Vals[i])) OperandList[NumOperands++] = MB; - Node.push_back(ElementVH(Vals[i], this)); + Node.push_back(WeakVH(Vals[i])); } } -void MDNode::Profile(FoldingSetNodeID &ID) const { - for (const_elem_iterator I = elem_begin(), E = elem_end(); I != E; ++I) - ID.AddPointer(*I); -} - MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { - LLVMContextImpl *pImpl = Context.pImpl; - FoldingSetNodeID ID; - for (unsigned i = 0; i != NumVals; ++i) - ID.AddPointer(Vals[i]); - - pImpl->ConstantsLock.reader_acquire(); - void *InsertPoint; - MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - pImpl->ConstantsLock.reader_release(); + std::vector V; + V.reserve(NumVals); + for (unsigned i = 0; i < NumVals; ++i) + V.push_back(Vals[i]); - if (!N) { - sys::SmartScopedWriter Writer(pImpl->ConstantsLock); - N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - if (!N) { - // InsertPoint will have been set by the FindNodeOrInsertPos call. - N = new MDNode(Context, Vals, NumVals); - pImpl->MDNodeSet.InsertNode(N, InsertPoint); - } - } - - return N; + // FIXME : Avoid creating duplicate node. + return new MDNode(Context, &V[0], V.size()); } /// dropAllReferences - Remove all uses and clear node vector. @@ -112,73 +93,10 @@ void MDNode::dropAllReferences() { } MDNode::~MDNode() { - getType()->getContext().pImpl->MDNodeSet.RemoveNode(this); + getType()->getContext().pImpl->MDNodes.erase(this); dropAllReferences(); } -// Replace value from this node's element list. -void MDNode::replaceElement(Value *From, Value *To) { - if (From == To || !getType()) - return; - LLVMContext &Context = getType()->getContext(); - LLVMContextImpl *pImpl = Context.pImpl; - - // Find value. This is a linear search, do something if it consumes - // lot of time. It is possible that to have multiple instances of - // From in this MDNode's element list. - SmallVector Indexes; - unsigned Index = 0; - for (SmallVector::iterator I = Node.begin(), - E = Node.end(); I != E; ++I, ++Index) { - Value *V = *I; - if (V && V == From) - Indexes.push_back(Index); - } - - if (Indexes.empty()) - return; - - // Remove "this" from the context map. - { - sys::SmartScopedWriter Writer(pImpl->ConstantsLock); - pImpl->MDNodeSet.RemoveNode(this); - } - - // Replace From element(s) in place. - for (SmallVector::iterator I = Indexes.begin(), E = Indexes.end(); - I != E; ++I) { - unsigned Index = *I; - Node[Index] = ElementVH(To, this); - } - - // Insert updated "this" into the context's folding node set. - // If a node with same element list already exist then before inserting - // updated "this" into the folding node set, replace all uses of existing - // node with updated "this" node. - FoldingSetNodeID ID; - Profile(ID); - pImpl->ConstantsLock.reader_acquire(); - void *InsertPoint; - MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - pImpl->ConstantsLock.reader_release(); - - if (N) { - N->replaceAllUsesWith(this); - delete N; - N = 0; - } - - { - sys::SmartScopedWriter Writer(pImpl->ConstantsLock); - N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - if (!N) { - // InsertPoint will have been set by the FindNodeOrInsertPos call. - N = this; - pImpl->MDNodeSet.InsertNode(N, InsertPoint); - } - } -} - //===----------------------------------------------------------------------===// //NamedMDNode implementation // diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/VMCore/MetadataTest.cpp index cdf5a6e6b90..f174fb65b81 100644 --- a/unittests/VMCore/MetadataTest.cpp +++ b/unittests/VMCore/MetadataTest.cpp @@ -85,7 +85,7 @@ TEST(MDNodeTest, Simple) { MDNode *n2 = MDNode::get(Context, &c1, 1); MDNode *n3 = MDNode::get(Context, &V[0], 3); EXPECT_NE(n1, n2); - EXPECT_EQ(n1, n3); + // FIXME: Enable uniqueness test. EXPECT_EQ(n1, n3); EXPECT_EQ(3u, n1->getNumElements()); EXPECT_EQ(s1, n1->getElement(0));