Devang Patel | a4f43fb | 2009-07-28 21:49:47 +0000 | [diff] [blame] | 1 | //===-- Metadata.cpp - Implement Metadata classes -------------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file implements the Metadata classes. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Owen Anderson | 0087fe6 | 2009-07-31 21:35:40 +0000 | [diff] [blame] | 14 | #include "LLVMContextImpl.h" |
Devang Patel | a4f43fb | 2009-07-28 21:49:47 +0000 | [diff] [blame] | 15 | #include "llvm/Metadata.h" |
Owen Anderson | 0087fe6 | 2009-07-31 21:35:40 +0000 | [diff] [blame] | 16 | #include "llvm/LLVMContext.h" |
Devang Patel | 05a26fb | 2009-07-29 00:33:07 +0000 | [diff] [blame] | 17 | #include "llvm/Module.h" |
Devang Patel | 18dfdc9 | 2009-07-29 17:16:17 +0000 | [diff] [blame] | 18 | #include "SymbolTableListTraitsImpl.h" |
Devang Patel | a4f43fb | 2009-07-28 21:49:47 +0000 | [diff] [blame] | 19 | using namespace llvm; |
| 20 | |
| 21 | //===----------------------------------------------------------------------===// |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 22 | //MetadataBase implementation |
| 23 | // |
| 24 | |
| 25 | /// resizeOperands - Metadata keeps track of other metadata uses using |
| 26 | /// OperandList. Resize this list to hold anticipated number of metadata |
| 27 | /// operands. |
| 28 | void MetadataBase::resizeOperands(unsigned NumOps) { |
| 29 | unsigned e = getNumOperands(); |
| 30 | if (NumOps == 0) { |
| 31 | NumOps = e*2; |
| 32 | if (NumOps < 2) NumOps = 2; |
| 33 | } else if (NumOps > NumOperands) { |
| 34 | // No resize needed. |
| 35 | if (ReservedSpace >= NumOps) return; |
| 36 | } else if (NumOps == NumOperands) { |
| 37 | if (ReservedSpace == NumOps) return; |
| 38 | } else { |
| 39 | return; |
| 40 | } |
| 41 | |
| 42 | ReservedSpace = NumOps; |
| 43 | Use *OldOps = OperandList; |
| 44 | Use *NewOps = allocHungoffUses(NumOps); |
| 45 | std::copy(OldOps, OldOps + e, NewOps); |
| 46 | OperandList = NewOps; |
| 47 | if (OldOps) Use::zap(OldOps, OldOps + e, true); |
| 48 | } |
| 49 | //===----------------------------------------------------------------------===// |
Owen Anderson | 0087fe6 | 2009-07-31 21:35:40 +0000 | [diff] [blame] | 50 | //MDString implementation |
| 51 | // |
| 52 | MDString *MDString::get(LLVMContext &Context, const StringRef &Str) { |
| 53 | LLVMContextImpl *pImpl = Context.pImpl; |
| 54 | sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); |
| 55 | StringMapEntry<MDString *> &Entry = |
| 56 | pImpl->MDStringCache.GetOrCreateValue(Str); |
| 57 | MDString *&S = Entry.getValue(); |
| 58 | if (!S) S = new MDString(Entry.getKeyData(), |
| 59 | Entry.getKeyLength()); |
| 60 | |
| 61 | return S; |
| 62 | } |
| 63 | |
| 64 | //===----------------------------------------------------------------------===// |
Devang Patel | a4f43fb | 2009-07-28 21:49:47 +0000 | [diff] [blame] | 65 | //MDNode implementation |
| 66 | // |
| 67 | MDNode::MDNode(Value*const* Vals, unsigned NumVals) |
| 68 | : MetadataBase(Type::MetadataTy, Value::MDNodeVal) { |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 69 | NumOperands = 0; |
| 70 | resizeOperands(NumVals); |
| 71 | for (unsigned i = 0; i != NumVals; ++i) { |
| 72 | // Only record metadata uses. |
| 73 | if (MetadataBase *MB = dyn_cast_or_null<MetadataBase>(Vals[i])) |
| 74 | OperandList[NumOperands++] = MB; |
Devang Patel | a4f43fb | 2009-07-28 21:49:47 +0000 | [diff] [blame] | 75 | Node.push_back(WeakVH(Vals[i])); |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 76 | } |
Devang Patel | a4f43fb | 2009-07-28 21:49:47 +0000 | [diff] [blame] | 77 | } |
| 78 | |
Owen Anderson | 0087fe6 | 2009-07-31 21:35:40 +0000 | [diff] [blame] | 79 | MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { |
| 80 | LLVMContextImpl *pImpl = Context.pImpl; |
Owen Anderson | 13234f8 | 2009-08-10 18:16:08 +0000 | [diff] [blame] | 81 | std::vector<Value*> V; |
| 82 | V.reserve(NumVals); |
| 83 | for (unsigned i = 0; i < NumVals; ++i) |
| 84 | V.push_back(Vals[i]); |
Owen Anderson | 0087fe6 | 2009-07-31 21:35:40 +0000 | [diff] [blame] | 85 | |
Devang Patel | 2c6c743 | 2009-08-10 22:31:31 +0000 | [diff] [blame] | 86 | return pImpl->MDNodes.getOrCreate(Type::MetadataTy, V); |
Owen Anderson | 0087fe6 | 2009-07-31 21:35:40 +0000 | [diff] [blame] | 87 | } |
| 88 | |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 89 | /// dropAllReferences - Remove all uses and clear node vector. |
| 90 | void MDNode::dropAllReferences() { |
| 91 | User::dropAllReferences(); |
| 92 | Node.clear(); |
| 93 | } |
| 94 | |
Devang Patel | 9b4ea1c | 2009-08-10 22:59:46 +0000 | [diff] [blame] | 95 | static std::vector<Value*> getValType(MDNode *N) { |
| 96 | std::vector<Value*> Elements; |
| 97 | Elements.reserve(N->getNumElements()); |
| 98 | for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) |
| 99 | Elements.push_back(N->getElement(i)); |
| 100 | return Elements; |
| 101 | } |
| 102 | |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 103 | MDNode::~MDNode() { |
| 104 | dropAllReferences(); |
Devang Patel | 9b4ea1c | 2009-08-10 22:59:46 +0000 | [diff] [blame] | 105 | getType()->getContext().pImpl->MDNodes.remove(this); |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 106 | } |
Devang Patel | 5c310be | 2009-08-11 18:01:24 +0000 | [diff] [blame^] | 107 | |
Devang Patel | 05a26fb | 2009-07-29 00:33:07 +0000 | [diff] [blame] | 108 | //===----------------------------------------------------------------------===// |
| 109 | //NamedMDNode implementation |
| 110 | // |
Devang Patel | 4a942d0 | 2009-07-29 21:58:56 +0000 | [diff] [blame] | 111 | NamedMDNode::NamedMDNode(const Twine &N, MetadataBase*const* MDs, |
| 112 | unsigned NumMDs, Module *ParentModule) |
Benjamin Kramer | 5656e4f | 2009-07-30 15:35:55 +0000 | [diff] [blame] | 113 | : MetadataBase(Type::MetadataTy, Value::NamedMDNodeVal), Parent(0) { |
Devang Patel | 18dfdc9 | 2009-07-29 17:16:17 +0000 | [diff] [blame] | 114 | setName(N); |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 115 | NumOperands = 0; |
| 116 | resizeOperands(NumMDs); |
| 117 | |
| 118 | for (unsigned i = 0; i != NumMDs; ++i) { |
| 119 | if (MDs[i]) |
| 120 | OperandList[NumOperands++] = MDs[i]; |
Devang Patel | 05a26fb | 2009-07-29 00:33:07 +0000 | [diff] [blame] | 121 | Node.push_back(WeakMetadataVH(MDs[i])); |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 122 | } |
Devang Patel | 4a942d0 | 2009-07-29 21:58:56 +0000 | [diff] [blame] | 123 | if (ParentModule) |
| 124 | ParentModule->getNamedMDList().push_back(this); |
Devang Patel | 05a26fb | 2009-07-29 00:33:07 +0000 | [diff] [blame] | 125 | } |
Devang Patel | 79238d7 | 2009-08-03 06:19:01 +0000 | [diff] [blame] | 126 | |
Devang Patel | 5c310be | 2009-08-11 18:01:24 +0000 | [diff] [blame^] | 127 | NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) { |
| 128 | assert (NMD && "Invalid source NamedMDNode!"); |
| 129 | SmallVector<MetadataBase *, 4> Elems; |
| 130 | for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) |
| 131 | Elems.push_back(NMD->getElement(i)); |
| 132 | return new NamedMDNode(NMD->getName().data(), Elems.data(), Elems.size(), M); |
| 133 | } |
| 134 | |
Devang Patel | 79238d7 | 2009-08-03 06:19:01 +0000 | [diff] [blame] | 135 | /// eraseFromParent - Drop all references and remove the node from parent |
| 136 | /// module. |
| 137 | void NamedMDNode::eraseFromParent() { |
Devang Patel | 79238d7 | 2009-08-03 06:19:01 +0000 | [diff] [blame] | 138 | getParent()->getNamedMDList().erase(this); |
| 139 | } |
| 140 | |
| 141 | /// dropAllReferences - Remove all uses and clear node vector. |
| 142 | void NamedMDNode::dropAllReferences() { |
Devang Patel | d7fd6ab | 2009-08-03 22:51:10 +0000 | [diff] [blame] | 143 | User::dropAllReferences(); |
Devang Patel | 79238d7 | 2009-08-03 06:19:01 +0000 | [diff] [blame] | 144 | Node.clear(); |
| 145 | } |
| 146 | |
| 147 | NamedMDNode::~NamedMDNode() { |
| 148 | dropAllReferences(); |
| 149 | } |