From: Devang Patel Date: Mon, 3 Aug 2009 22:51:10 +0000 (+0000) Subject: Keep track of metadata used by other metadata. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=4771e16fa96f41e62fc54578b6f656a52c23b61c;p=oota-llvm.git Keep track of metadata used by other metadata. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78012 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 7b48d8afbfa..d0f3477e724 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -16,7 +16,7 @@ #ifndef LLVM_MDNODE_H #define LLVM_MDNODE_H -#include "llvm/Value.h" +#include "llvm/User.h" #include "llvm/Type.h" #include "llvm/OperandTraits.h" #include "llvm/ADT/FoldingSet.h" @@ -31,11 +31,17 @@ class LLVMContext; //===----------------------------------------------------------------------===// // MetadataBase - A base class for MDNode, MDString and NamedMDNode. -class MetadataBase : public Value { +class MetadataBase : public User { +private: + /// ReservedSpace - The number of operands actually allocated. NumOperands is + /// the number actually in use. + unsigned ReservedSpace; + protected: MetadataBase(const Type *Ty, unsigned scid) - : Value(Ty, scid) {} + : User(Ty, scid, NULL, 0), ReservedSpace(0) {} + void resizeOperands(unsigned NumOps); public: /// getType() specialization - Type is always MetadataTy. /// @@ -64,13 +70,19 @@ public: /// MDString is always unnamd. class MDString : public MetadataBase { MDString(const MDString &); // DO NOT IMPLEMENT - StringRef Str; + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + unsigned getNumOperands(); // DO NOT IMPLEMENT + StringRef Str; protected: explicit MDString(const char *begin, unsigned l) : MetadataBase(Type::MetadataTy, Value::MDStringVal), Str(begin, l) {} public: + // Do not allocate any space for operands. + void *operator new(size_t s) { + return User::operator new(s, 0); + } static MDString *get(LLVMContext &Context, const StringRef &Str); StringRef getString() const { return Str; } @@ -97,38 +109,49 @@ public: /// These contain a list of the values that represent the metadata. /// MDNode is always unnamed. class MDNode : public MetadataBase, public FoldingSetNode { - MDNode(const MDNode &); // DO NOT IMPLEMENT + 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(); } SmallVector Node; - typedef SmallVectorImpl::iterator elem_iterator; - protected: explicit MDNode(Value*const* Vals, unsigned NumVals); public: + // Do not allocate any space for operands. + void *operator new(size_t s) { + return User::operator new(s, 0); + } + // Constructors and destructors. static MDNode *get(LLVMContext &Context, Value* const* Vals, unsigned NumVals); - - typedef SmallVectorImpl::const_iterator const_elem_iterator; + /// dropAllReferences - Remove all uses and clear node vector. + void dropAllReferences(); + + /// ~MDNode - Destroy NamedMDNode. + ~MDNode(); + + /// getElement - Return specified element. Value *getElement(unsigned i) const { + assert (getNumElements() > i && "Invalid element number!"); return Node[i]; } + /// getNumElements - Return number of MDNode elements. unsigned getNumElements() const { return Node.size(); } - bool elem_empty() const { - return Node.empty(); - } - - const_elem_iterator elem_begin() const { - return Node.begin(); - } - - const_elem_iterator elem_end() const { - return Node.end(); - } + // Element access + 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(); } + const_elem_iterator elem_end() const { return Node.end(); } + elem_iterator elem_begin() { return Node.begin(); } + elem_iterator elem_end() { return Node.end(); } /// getType() specialization - Type is always MetadataTy. /// @@ -183,10 +206,13 @@ template class NamedMDNode : public MetadataBase, public ilist_node { friend class SymbolTableListTraits; - NamedMDNode(const NamedMDNode &); // DO NOT IMPLEMENT - friend class LLVMContextImpl; + NamedMDNode(const NamedMDNode &); // 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(); } + Module *Parent; SmallVector Node; typedef SmallVectorImpl::iterator elem_iterator; @@ -195,6 +221,10 @@ protected: explicit NamedMDNode(const Twine &N, MetadataBase*const* Vals, unsigned NumVals, Module *M = 0); public: + // Do not allocate any space for operands. + void *operator new(size_t s) { + return User::operator new(s, 0); + } static NamedMDNode *Create(const Twine &N, MetadataBase*const*MDs, unsigned NumMDs, Module *M = 0) { return new NamedMDNode(N, MDs, NumMDs, M); @@ -207,39 +237,38 @@ public: /// dropAllReferences - Remove all uses and clear node vector. void dropAllReferences(); + /// ~NamedMDNode - Destroy NamedMDNode. ~NamedMDNode(); - typedef SmallVectorImpl::const_iterator const_elem_iterator; - /// getParent - Get the module that holds this named metadata collection. inline Module *getParent() { return Parent; } inline const Module *getParent() const { return Parent; } void setParent(Module *M) { Parent = M; } + /// getElement - Return specified element. MetadataBase *getElement(unsigned i) const { + assert (getNumElements() > i && "Invalid element number!"); return Node[i]; } + /// getNumElements - Return number of NamedMDNode elements. unsigned getNumElements() const { return Node.size(); } /// addElement - Add metadata element. void addElement(MetadataBase *M) { + resizeOperands(0); + OperandList[NumOperands++] = M; Node.push_back(WeakMetadataVH(M)); } - bool elem_empty() const { - return Node.empty(); - } - - const_elem_iterator elem_begin() const { - return Node.begin(); - } - - const_elem_iterator elem_end() const { - return Node.end(); - } + typedef SmallVectorImpl::const_iterator const_elem_iterator; + bool elem_empty() const { return Node.empty(); } + const_elem_iterator elem_begin() const { return Node.begin(); } + const_elem_iterator elem_end() const { return Node.end(); } + elem_iterator elem_begin() { return Node.begin(); } + elem_iterator elem_end() { return Node.end(); } /// getType() specialization - Type is always MetadataTy. /// diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index f548e549441..b44441fdb3f 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -18,6 +18,34 @@ #include "SymbolTableListTraitsImpl.h" using namespace llvm; +//===----------------------------------------------------------------------===// +//MetadataBase implementation +// + +/// resizeOperands - Metadata keeps track of other metadata uses using +/// OperandList. Resize this list to hold anticipated number of metadata +/// operands. +void MetadataBase::resizeOperands(unsigned NumOps) { + unsigned e = getNumOperands(); + if (NumOps == 0) { + NumOps = e*2; + if (NumOps < 2) NumOps = 2; + } else if (NumOps > NumOperands) { + // No resize needed. + if (ReservedSpace >= NumOps) return; + } else if (NumOps == NumOperands) { + if (ReservedSpace == NumOps) return; + } else { + return; + } + + ReservedSpace = NumOps; + Use *OldOps = OperandList; + Use *NewOps = allocHungoffUses(NumOps); + std::copy(OldOps, OldOps + e, NewOps); + OperandList = NewOps; + if (OldOps) Use::zap(OldOps, OldOps + e, true); +} //===----------------------------------------------------------------------===// //MDString implementation // @@ -38,8 +66,14 @@ MDString *MDString::get(LLVMContext &Context, const StringRef &Str) { // MDNode::MDNode(Value*const* Vals, unsigned NumVals) : MetadataBase(Type::MetadataTy, Value::MDNodeVal) { - for (unsigned i = 0; i != NumVals; ++i) + NumOperands = 0; + resizeOperands(NumVals); + for (unsigned i = 0; i != NumVals; ++i) { + // Only record metadata uses. + if (MetadataBase *MB = dyn_cast_or_null(Vals[i])) + OperandList[NumOperands++] = MB; Node.push_back(WeakVH(Vals[i])); + } } void MDNode::Profile(FoldingSetNodeID &ID) const { @@ -71,6 +105,15 @@ MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { return N; } +/// dropAllReferences - Remove all uses and clear node vector. +void MDNode::dropAllReferences() { + User::dropAllReferences(); + Node.clear(); +} + +MDNode::~MDNode() { + dropAllReferences(); +} //===----------------------------------------------------------------------===// //NamedMDNode implementation // @@ -78,8 +121,14 @@ NamedMDNode::NamedMDNode(const Twine &N, MetadataBase*const* MDs, unsigned NumMDs, Module *ParentModule) : MetadataBase(Type::MetadataTy, Value::NamedMDNodeVal), Parent(0) { setName(N); - for (unsigned i = 0; i != NumMDs; ++i) + NumOperands = 0; + resizeOperands(NumMDs); + + for (unsigned i = 0; i != NumMDs; ++i) { + if (MDs[i]) + OperandList[NumOperands++] = MDs[i]; Node.push_back(WeakMetadataVH(MDs[i])); + } if (ParentModule) ParentModule->getNamedMDList().push_back(this); } @@ -87,13 +136,12 @@ NamedMDNode::NamedMDNode(const Twine &N, MetadataBase*const* MDs, /// eraseFromParent - Drop all references and remove the node from parent /// module. void NamedMDNode::eraseFromParent() { - dropAllReferences(); getParent()->getNamedMDList().erase(this); } /// dropAllReferences - Remove all uses and clear node vector. void NamedMDNode::dropAllReferences() { - // FIXME: Update metadata use list. + User::dropAllReferences(); Node.clear(); }