diff options
Diffstat (limited to 'lib/VMCore/Metadata.cpp')
-rw-r--r-- | lib/VMCore/Metadata.cpp | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index f548e54944..b44441fdb3 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -19,6 +19,34 @@ 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 // MDString *MDString::get(LLVMContext &Context, const StringRef &Str) { @@ -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<MetadataBase>(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(); } |