summaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2009-08-03 22:51:10 +0000
committerDevang Patel <dpatel@apple.com>2009-08-03 22:51:10 +0000
commit4771e16fa96f41e62fc54578b6f656a52c23b61c (patch)
treeff574c394c4f67b9e3a8f917e27530c5f2cc46d1 /lib/VMCore
parent5e44e472d61fd113095e7b0825a0146703e500d3 (diff)
downloadexternal_llvm-4771e16fa96f41e62fc54578b6f656a52c23b61c.zip
external_llvm-4771e16fa96f41e62fc54578b6f656a52c23b61c.tar.gz
external_llvm-4771e16fa96f41e62fc54578b6f656a52c23b61c.tar.bz2
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
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/Metadata.cpp56
1 files changed, 52 insertions, 4 deletions
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index f548e54..b44441f 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();
}