blob: eb4544c98249d7eaa410845da9a52c8e890131cc [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
79void MDNode::Profile(FoldingSetNodeID &ID) const {
80 for (const_elem_iterator I = elem_begin(), E = elem_end(); I != E; ++I)
81 ID.AddPointer(*I);
82}
Devang Patel05a26fb2009-07-29 00:33:07 +000083
Owen Anderson0087fe62009-07-31 21:35:40 +000084MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
85 LLVMContextImpl *pImpl = Context.pImpl;
Owen Anderson13234f82009-08-10 18:16:08 +000086 std::vector<Value*> V;
87 V.reserve(NumVals);
88 for (unsigned i = 0; i < NumVals; ++i)
89 V.push_back(Vals[i]);
Owen Anderson0087fe62009-07-31 21:35:40 +000090
Owen Anderson13234f82009-08-10 18:16:08 +000091 return pImpl->MDNodeSet.getOrCreate(Type::MetadataTy, V);
Owen Anderson0087fe62009-07-31 21:35:40 +000092}
93
Devang Pateld7fd6ab2009-08-03 22:51:10 +000094/// dropAllReferences - Remove all uses and clear node vector.
95void MDNode::dropAllReferences() {
96 User::dropAllReferences();
97 Node.clear();
98}
99
100MDNode::~MDNode() {
101 dropAllReferences();
102}
Devang Patel05a26fb2009-07-29 00:33:07 +0000103//===----------------------------------------------------------------------===//
104//NamedMDNode implementation
105//
Devang Patel4a942d02009-07-29 21:58:56 +0000106NamedMDNode::NamedMDNode(const Twine &N, MetadataBase*const* MDs,
107 unsigned NumMDs, Module *ParentModule)
Benjamin Kramer5656e4f2009-07-30 15:35:55 +0000108 : MetadataBase(Type::MetadataTy, Value::NamedMDNodeVal), Parent(0) {
Devang Patel18dfdc92009-07-29 17:16:17 +0000109 setName(N);
Devang Pateld7fd6ab2009-08-03 22:51:10 +0000110 NumOperands = 0;
111 resizeOperands(NumMDs);
112
113 for (unsigned i = 0; i != NumMDs; ++i) {
114 if (MDs[i])
115 OperandList[NumOperands++] = MDs[i];
Devang Patel05a26fb2009-07-29 00:33:07 +0000116 Node.push_back(WeakMetadataVH(MDs[i]));
Devang Pateld7fd6ab2009-08-03 22:51:10 +0000117 }
Devang Patel4a942d02009-07-29 21:58:56 +0000118 if (ParentModule)
119 ParentModule->getNamedMDList().push_back(this);
Devang Patel05a26fb2009-07-29 00:33:07 +0000120}
Devang Patel79238d72009-08-03 06:19:01 +0000121
122/// eraseFromParent - Drop all references and remove the node from parent
123/// module.
124void NamedMDNode::eraseFromParent() {
Devang Patel79238d72009-08-03 06:19:01 +0000125 getParent()->getNamedMDList().erase(this);
126}
127
128/// dropAllReferences - Remove all uses and clear node vector.
129void NamedMDNode::dropAllReferences() {
Devang Pateld7fd6ab2009-08-03 22:51:10 +0000130 User::dropAllReferences();
Devang Patel79238d72009-08-03 06:19:01 +0000131 Node.clear();
132}
133
134NamedMDNode::~NamedMDNode() {
135 dropAllReferences();
136}