1 //===-- Metadata.cpp - Implement Metadata classes -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
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
28 void MetadataBase::resizeOperands(unsigned NumOps
) {
29 unsigned e
= getNumOperands();
32 if (NumOps
< 2) NumOps
= 2;
33 } else if (NumOps
> NumOperands
) {
35 if (ReservedSpace
>= NumOps
) return;
36 } else if (NumOps
== NumOperands
) {
37 if (ReservedSpace
== NumOps
) return;
42 ReservedSpace
= NumOps
;
43 Use
*OldOps
= OperandList
;
44 Use
*NewOps
= allocHungoffUses(NumOps
);
45 std::copy(OldOps
, OldOps
+ e
, 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());
64 //===----------------------------------------------------------------------===//
65 //MDNode implementation
67 MDNode::MDNode(LLVMContext
&C
, Value
*const* Vals
, unsigned NumVals
)
68 : MetadataBase(Type::getMetadataTy(C
), Value::MDNodeVal
) {
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
;
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
)
87 MDNode
*MDNode::get(LLVMContext
&Context
, Value
*const* Vals
, unsigned NumVals
) {
88 LLVMContextImpl
*pImpl
= Context
.pImpl
;
90 for (unsigned i
= 0; i
!= NumVals
; ++i
)
91 ID
.AddPointer(Vals
[i
]);
93 pImpl
->ConstantsLock
.reader_acquire();
95 MDNode
*N
= pImpl
->MDNodeSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
96 pImpl
->ConstantsLock
.reader_release();
99 sys::SmartScopedWriter
<true> Writer(pImpl
->ConstantsLock
);
100 N
= pImpl
->MDNodeSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
102 // InsertPoint will have been set by the FindNodeOrInsertPos call.
103 N
= new MDNode(Context
, Vals
, NumVals
);
104 pImpl
->MDNodeSet
.InsertNode(N
, InsertPoint
);
111 /// dropAllReferences - Remove all uses and clear node vector.
112 void MDNode::dropAllReferences() {
113 User::dropAllReferences();
119 LLVMContextImpl
*pImpl
= getType()->getContext().pImpl
;
120 sys::SmartScopedWriter
<true> Writer(pImpl
->ConstantsLock
);
121 pImpl
->MDNodeSet
.RemoveNode(this);
126 // Replace value from this node's element list.
127 void MDNode::replaceElement(Value
*From
, Value
*To
) {
128 if (From
== To
|| !getType())
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
;
138 for (SmallVector
<ElementVH
, 4>::iterator I
= Node
.begin(),
139 E
= Node
.end(); I
!= E
; ++I
, ++Index
) {
142 Indexes
.push_back(Index
);
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
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
++) {
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
);
170 for (SmallVector
<unsigned, 4>::iterator OI
= OpIndexes
.begin(),
171 OE
= OpIndexes
.end(); OI
!= OE
; ++OI
)
175 // Replace From element(s) in place.
176 for (SmallVector
<unsigned, 4>::iterator I
= Indexes
.begin(), E
= Indexes
.end();
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.
188 pImpl
->ConstantsLock
.reader_acquire();
190 MDNode
*N
= pImpl
->MDNodeSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
191 pImpl
->ConstantsLock
.reader_release();
194 N
->replaceAllUsesWith(this);
200 sys::SmartScopedWriter
<true> Writer(pImpl
->ConstantsLock
);
201 N
= pImpl
->MDNodeSet
.FindNodeOrInsertPos(ID
, InsertPoint
);
203 // InsertPoint will have been set by the FindNodeOrInsertPos call.
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) {
219 resizeOperands(NumMDs
);
221 for (unsigned i
= 0; i
!= NumMDs
; ++i
) {
223 OperandList
[NumOperands
++] = MDs
[i
];
224 Node
.push_back(WeakMetadataVH(MDs
[i
]));
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
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();
251 NamedMDNode::~NamedMDNode() {