make -debug-pass=Executions show information about what call graph nodes
[llvm/avr.git] / lib / VMCore / Metadata.cpp
blob1163b4709ceb05eedc03caad2b092a25afe77f16
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.
12 //===----------------------------------------------------------------------===//
14 #include "LLVMContextImpl.h"
15 #include "llvm/Metadata.h"
16 #include "llvm/LLVMContext.h"
17 #include "llvm/Module.h"
18 #include "SymbolTableListTraitsImpl.h"
19 using namespace llvm;
21 //===----------------------------------------------------------------------===//
22 //MetadataBase implementation
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;
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);
49 //===----------------------------------------------------------------------===//
50 //MDString implementation
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(Context, Entry.getKeyData(),
59 Entry.getKeyLength());
61 return S;
64 //===----------------------------------------------------------------------===//
65 //MDNode implementation
67 MDNode::MDNode(LLVMContext &C, Value*const* Vals, unsigned NumVals)
68 : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
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;
75 else if(Vals[i] &&
76 Vals[i]->getType()->getTypeID() == Type::MetadataTyID)
77 OperandList[NumOperands++] = Vals[i];
78 Node.push_back(ElementVH(Vals[i], this));
82 void MDNode::Profile(FoldingSetNodeID &ID) const {
83 for (const_elem_iterator I = elem_begin(), E = elem_end(); I != E; ++I)
84 ID.AddPointer(*I);
87 MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
88 LLVMContextImpl *pImpl = Context.pImpl;
89 FoldingSetNodeID ID;
90 for (unsigned i = 0; i != NumVals; ++i)
91 ID.AddPointer(Vals[i]);
93 pImpl->ConstantsLock.reader_acquire();
94 void *InsertPoint;
95 MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
96 pImpl->ConstantsLock.reader_release();
98 if (!N) {
99 sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
100 N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
101 if (!N) {
102 // InsertPoint will have been set by the FindNodeOrInsertPos call.
103 N = new MDNode(Context, Vals, NumVals);
104 pImpl->MDNodeSet.InsertNode(N, InsertPoint);
108 return N;
111 /// dropAllReferences - Remove all uses and clear node vector.
112 void MDNode::dropAllReferences() {
113 User::dropAllReferences();
114 Node.clear();
117 MDNode::~MDNode() {
119 LLVMContextImpl *pImpl = getType()->getContext().pImpl;
120 sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
121 pImpl->MDNodeSet.RemoveNode(this);
123 dropAllReferences();
126 // Replace value from this node's element list.
127 void MDNode::replaceElement(Value *From, Value *To) {
128 if (From == To || !getType())
129 return;
130 LLVMContext &Context = getType()->getContext();
131 LLVMContextImpl *pImpl = Context.pImpl;
133 // Find value. This is a linear search, do something if it consumes
134 // lot of time. It is possible that to have multiple instances of
135 // From in this MDNode's element list.
136 SmallVector<unsigned, 4> Indexes;
137 unsigned Index = 0;
138 for (SmallVector<ElementVH, 4>::iterator I = Node.begin(),
139 E = Node.end(); I != E; ++I, ++Index) {
140 Value *V = *I;
141 if (V && V == From)
142 Indexes.push_back(Index);
145 if (Indexes.empty())
146 return;
148 // Remove "this" from the context map.
150 sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
151 pImpl->MDNodeSet.RemoveNode(this);
154 // MDNode only lists metadata elements in operand list, because MDNode
155 // used by MDNode is considered a valid use. However on the side, MDNode
156 // using a non-metadata value is not considered a "use" of non-metadata
157 // value.
158 SmallVector<unsigned, 4> OpIndexes;
159 unsigned OpIndex = 0;
160 for (User::op_iterator OI = op_begin(), OE = op_end();
161 OI != OE; ++OI, OpIndex++) {
162 if (*OI == From)
163 OpIndexes.push_back(OpIndex);
165 if (MetadataBase *MDTo = dyn_cast_or_null<MetadataBase>(To)) {
166 for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(),
167 OE = OpIndexes.end(); OI != OE; ++OI)
168 setOperand(*OI, MDTo);
169 } else {
170 for (SmallVector<unsigned, 4>::iterator OI = OpIndexes.begin(),
171 OE = OpIndexes.end(); OI != OE; ++OI)
172 setOperand(*OI, 0);
175 // Replace From element(s) in place.
176 for (SmallVector<unsigned, 4>::iterator I = Indexes.begin(), E = Indexes.end();
177 I != E; ++I) {
178 unsigned Index = *I;
179 Node[Index] = ElementVH(To, this);
182 // Insert updated "this" into the context's folding node set.
183 // If a node with same element list already exist then before inserting
184 // updated "this" into the folding node set, replace all uses of existing
185 // node with updated "this" node.
186 FoldingSetNodeID ID;
187 Profile(ID);
188 pImpl->ConstantsLock.reader_acquire();
189 void *InsertPoint;
190 MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
191 pImpl->ConstantsLock.reader_release();
193 if (N) {
194 N->replaceAllUsesWith(this);
195 delete N;
196 N = 0;
200 sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
201 N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
202 if (!N) {
203 // InsertPoint will have been set by the FindNodeOrInsertPos call.
204 N = this;
205 pImpl->MDNodeSet.InsertNode(N, InsertPoint);
210 //===----------------------------------------------------------------------===//
211 //NamedMDNode implementation
213 NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N,
214 MetadataBase*const* MDs,
215 unsigned NumMDs, Module *ParentModule)
216 : MetadataBase(Type::getMetadataTy(C), Value::NamedMDNodeVal), Parent(0) {
217 setName(N);
218 NumOperands = 0;
219 resizeOperands(NumMDs);
221 for (unsigned i = 0; i != NumMDs; ++i) {
222 if (MDs[i])
223 OperandList[NumOperands++] = MDs[i];
224 Node.push_back(WeakMetadataVH(MDs[i]));
226 if (ParentModule)
227 ParentModule->getNamedMDList().push_back(this);
230 NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) {
231 assert (NMD && "Invalid source NamedMDNode!");
232 SmallVector<MetadataBase *, 4> Elems;
233 for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i)
234 Elems.push_back(NMD->getElement(i));
235 return new NamedMDNode(NMD->getContext(), NMD->getName().data(),
236 Elems.data(), Elems.size(), M);
239 /// eraseFromParent - Drop all references and remove the node from parent
240 /// module.
241 void NamedMDNode::eraseFromParent() {
242 getParent()->getNamedMDList().erase(this);
245 /// dropAllReferences - Remove all uses and clear node vector.
246 void NamedMDNode::dropAllReferences() {
247 User::dropAllReferences();
248 Node.clear();
251 NamedMDNode::~NamedMDNode() {
252 dropAllReferences();