blob: 4762a1055507829a9ebbc28fad30db0a946791e1 [file] [log] [blame]
Devang Patela4f43fb2009-07-28 21:49:47 +00001//===-- 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 Anderson0087fe62009-07-31 21:35:40 +000014#include "LLVMContextImpl.h"
Devang Patela4f43fb2009-07-28 21:49:47 +000015#include "llvm/Metadata.h"
Owen Anderson0087fe62009-07-31 21:35:40 +000016#include "llvm/LLVMContext.h"
Devang Patel05a26fb2009-07-29 00:33:07 +000017#include "llvm/Module.h"
Devang Patel18dfdc92009-07-29 17:16:17 +000018#include "SymbolTableListTraitsImpl.h"
Devang Patela4f43fb2009-07-28 21:49:47 +000019using namespace llvm;
20
21//===----------------------------------------------------------------------===//
Devang Pateld7fd6ab2009-08-03 22:51:10 +000022//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.
28void 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 Anderson0087fe62009-07-31 21:35:40 +000050//MDString implementation
51//
52MDString *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 Patela4f43fb2009-07-28 21:49:47 +000065//MDNode implementation
66//
67MDNode::MDNode(Value*const* Vals, unsigned NumVals)
68 : MetadataBase(Type::MetadataTy, Value::MDNodeVal) {
Devang Pateld7fd6ab2009-08-03 22:51:10 +000069 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 Patela4f43fb2009-07-28 21:49:47 +000075 Node.push_back(WeakVH(Vals[i]));
Devang Pateld7fd6ab2009-08-03 22:51:10 +000076 }
Devang Patela4f43fb2009-07-28 21:49:47 +000077}
78
Owen Anderson0087fe62009-07-31 21:35:40 +000079MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
80 LLVMContextImpl *pImpl = Context.pImpl;
Owen Anderson13234f82009-08-10 18:16:08 +000081 std::vector<Value*> V;
82 V.reserve(NumVals);
83 for (unsigned i = 0; i < NumVals; ++i)
84 V.push_back(Vals[i]);
Owen Anderson0087fe62009-07-31 21:35:40 +000085
Devang Patel2c6c7432009-08-10 22:31:31 +000086 return pImpl->MDNodes.getOrCreate(Type::MetadataTy, V);
Owen Anderson0087fe62009-07-31 21:35:40 +000087}
88
Devang Pateld7fd6ab2009-08-03 22:51:10 +000089/// dropAllReferences - Remove all uses and clear node vector.
90void MDNode::dropAllReferences() {
91 User::dropAllReferences();
92 Node.clear();
93}
94
Devang Patel9b4ea1c2009-08-10 22:59:46 +000095static 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 Pateld7fd6ab2009-08-03 22:51:10 +0000103MDNode::~MDNode() {
104 dropAllReferences();
Devang Patel9b4ea1c2009-08-10 22:59:46 +0000105 getType()->getContext().pImpl->MDNodes.remove(this);
Devang Pateld7fd6ab2009-08-03 22:51:10 +0000106}
Devang Patel5c310be2009-08-11 18:01:24 +0000107
Devang Patel05a26fb2009-07-29 00:33:07 +0000108//===----------------------------------------------------------------------===//
109//NamedMDNode implementation
110//
Devang Patel4a942d02009-07-29 21:58:56 +0000111NamedMDNode::NamedMDNode(const Twine &N, MetadataBase*const* MDs,
112 unsigned NumMDs, Module *ParentModule)
Benjamin Kramer5656e4f2009-07-30 15:35:55 +0000113 : MetadataBase(Type::MetadataTy, Value::NamedMDNodeVal), Parent(0) {
Devang Patel18dfdc92009-07-29 17:16:17 +0000114 setName(N);
Devang Pateld7fd6ab2009-08-03 22:51:10 +0000115 NumOperands = 0;
116 resizeOperands(NumMDs);
117
118 for (unsigned i = 0; i != NumMDs; ++i) {
119 if (MDs[i])
120 OperandList[NumOperands++] = MDs[i];
Devang Patel05a26fb2009-07-29 00:33:07 +0000121 Node.push_back(WeakMetadataVH(MDs[i]));
Devang Pateld7fd6ab2009-08-03 22:51:10 +0000122 }
Devang Patel4a942d02009-07-29 21:58:56 +0000123 if (ParentModule)
124 ParentModule->getNamedMDList().push_back(this);
Devang Patel05a26fb2009-07-29 00:33:07 +0000125}
Devang Patel79238d72009-08-03 06:19:01 +0000126
Devang Patel5c310be2009-08-11 18:01:24 +0000127NamedMDNode *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 Patel79238d72009-08-03 06:19:01 +0000135/// eraseFromParent - Drop all references and remove the node from parent
136/// module.
137void NamedMDNode::eraseFromParent() {
Devang Patel79238d72009-08-03 06:19:01 +0000138 getParent()->getNamedMDList().erase(this);
139}
140
141/// dropAllReferences - Remove all uses and clear node vector.
142void NamedMDNode::dropAllReferences() {
Devang Pateld7fd6ab2009-08-03 22:51:10 +0000143 User::dropAllReferences();
Devang Patel79238d72009-08-03 06:19:01 +0000144 Node.clear();
145}
146
147NamedMDNode::~NamedMDNode() {
148 dropAllReferences();
149}