//
//===----------------------------------------------------------------------===//
-#include "LLVMContextImpl.h"
#include "llvm/Metadata.h"
+#include "LLVMContextImpl.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Instruction.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "SymbolTableListTraitsImpl.h"
+#include "llvm/Support/ValueHandle.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MDString implementation.
//
+
+MDString::MDString(LLVMContext &C, StringRef S)
+ : MetadataBase(Type::getMetadataTy(C), Value::MDStringVal), Str(S) {}
+
MDString *MDString::get(LLVMContext &Context, StringRef Str) {
LLVMContextImpl *pImpl = Context.pImpl;
StringMapEntry<MDString *> &Entry =
StringMapEntry<MDString *> &Entry =
pImpl->MDStringCache.GetOrCreateValue(Str ? StringRef(Str) : StringRef());
MDString *&S = Entry.getValue();
- if (!S) new MDString(Context, Entry.getKey());
+ if (!S) S = new MDString(Context, Entry.getKey());
return S;
}
+//===----------------------------------------------------------------------===//
+// MDNodeElement implementation.
+//
+
+// Use CallbackVH to hold MDNode elements.
+namespace llvm {
+class MDNodeElement : public CallbackVH {
+ MDNode *Parent;
+public:
+ MDNodeElement() {}
+ MDNodeElement(Value *V, MDNode *P) : CallbackVH(V), Parent(P) {}
+ ~MDNodeElement() {}
+
+ virtual void deleted();
+ virtual void allUsesReplacedWith(Value *NV);
+};
+} // end namespace llvm.
+
+
+void MDNodeElement::deleted() {
+ Parent->replaceElement(this->operator Value*(), 0);
+}
+
+void MDNodeElement::allUsesReplacedWith(Value *NV) {
+ Parent->replaceElement(this->operator Value*(), NV);
+}
+
+
+
//===----------------------------------------------------------------------===//
// MDNode implementation.
//
-MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals)
+
+MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
+ bool isFunctionLocal)
: MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
NodeSize = NumVals;
- Node = new ElementVH[NodeSize];
- ElementVH *Ptr = Node;
+ Node = new MDNodeElement[NodeSize];
+ MDNodeElement *Ptr = Node;
for (unsigned i = 0; i != NumVals; ++i)
- *Ptr++ = ElementVH(Vals[i], this);
+ *Ptr++ = MDNodeElement(Vals[i], this);
+ if (isFunctionLocal)
+ SubclassData |= FunctionLocalBit;
}
void MDNode::Profile(FoldingSetNodeID &ID) const {
ID.AddPointer(getElement(i));
}
-MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
+MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals,
+ bool isFunctionLocal) {
LLVMContextImpl *pImpl = Context.pImpl;
FoldingSetNodeID ID;
for (unsigned i = 0; i != NumVals; ++i)
MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
if (!N) {
// InsertPoint will have been set by the FindNodeOrInsertPos call.
- N = new MDNode(Context, Vals, NumVals);
+ N = new MDNode(Context, Vals, NumVals, isFunctionLocal);
pImpl->MDNodeSet.InsertNode(N, InsertPoint);
}
return N;
Node = NULL;
}
+/// getElement - Return specified element.
+Value *MDNode::getElement(unsigned i) const {
+ assert(i < getNumElements() && "Invalid element number!");
+ return Node[i];
+}
+
+
+
// Replace value from this node's element list.
void MDNode::replaceElement(Value *From, Value *To) {
if (From == To || !getType())
for (SmallVector<unsigned, 4>::iterator I = Indexes.begin(), E = Indexes.end();
I != E; ++I) {
unsigned Index = *I;
- Node[Index] = ElementVH(To, this);
+ Node[Index] = MDNodeElement(To, this);
}
// Insert updated "this" into the context's folding node set.
}
}
+// getLocalFunction - Return false if MDNode's recursive function-localness is
+// invalid (local to more than one function). Return true otherwise. If MDNode
+// has one function to which it is local, set LocalFunction to that function.
+bool MDNode::getLocalFunction(Function *LocalFunction,
+ SmallPtrSet<MDNode *, 32> *VisitedMDNodes) {
+ if (!isFunctionLocal())
+ return true;
+
+ if (!VisitedMDNodes)
+ VisitedMDNodes = new SmallPtrSet<MDNode *, 32>();
+
+ if (!VisitedMDNodes->insert(this))
+ // MDNode has already been visited, nothing to do.
+ return true;
+
+ for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
+ Value *V = getElement(i);
+ if (!V) continue;
+
+ Function *LocalFunctionTemp = NULL;
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ LocalFunctionTemp = I->getParent()->getParent();
+ else if (MDNode *MD = dyn_cast<MDNode>(V))
+ if (!MD->getLocalFunction(LocalFunctionTemp, VisitedMDNodes))
+ // This MDNode's operand is function-locally invalid or local to a
+ // different function.
+ return false;
+
+ if (LocalFunctionTemp) {
+ if (!LocalFunction)
+ LocalFunction = LocalFunctionTemp;
+ else if (LocalFunction != LocalFunctionTemp)
+ // This MDNode contains operands that are local to different functions.
+ return false;
+ }
+ }
+
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// NamedMDNode implementation.
//
+static SmallVector<TrackingVH<MetadataBase>, 4> &getNMDOps(void *Operands) {
+ return *(SmallVector<TrackingVH<MetadataBase>, 4>*)Operands;
+}
+
NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N,
MetadataBase *const *MDs,
unsigned NumMDs, Module *ParentModule)
: MetadataBase(Type::getMetadataTy(C), Value::NamedMDNodeVal), Parent(0) {
setName(N);
-
+
+ Operands = new SmallVector<TrackingVH<MetadataBase>, 4>();
+
+ SmallVector<TrackingVH<MetadataBase>, 4> &Node = getNMDOps(Operands);
for (unsigned i = 0; i != NumMDs; ++i)
Node.push_back(TrackingVH<MetadataBase>(MDs[i]));
NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) {
assert(NMD && "Invalid source NamedMDNode!");
SmallVector<MetadataBase *, 4> Elems;
+ Elems.reserve(NMD->getNumElements());
+
for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i)
Elems.push_back(NMD->getElement(i));
return new NamedMDNode(NMD->getContext(), NMD->getName().data(),
Elems.data(), Elems.size(), M);
}
+NamedMDNode::~NamedMDNode() {
+ dropAllReferences();
+ delete &getNMDOps(Operands);
+}
+
+/// getNumElements - Return number of NamedMDNode elements.
+unsigned NamedMDNode::getNumElements() const {
+ return (unsigned)getNMDOps(Operands).size();
+}
+
+/// getElement - Return specified element.
+MetadataBase *NamedMDNode::getElement(unsigned i) const {
+ assert(i < getNumElements() && "Invalid element number!");
+ return getNMDOps(Operands)[i];
+}
+
+/// addElement - Add metadata element.
+void NamedMDNode::addElement(MetadataBase *M) {
+ getNMDOps(Operands).push_back(TrackingVH<MetadataBase>(M));
+}
+
/// eraseFromParent - Drop all references and remove the node from parent
/// module.
void NamedMDNode::eraseFromParent() {
/// dropAllReferences - Remove all uses and clear node vector.
void NamedMDNode::dropAllReferences() {
- Node.clear();
+ getNMDOps(Operands).clear();
}
-NamedMDNode::~NamedMDNode() {
- dropAllReferences();
-}
//===----------------------------------------------------------------------===//
// MetadataContextImpl implementation.
MDNode *getMD(unsigned Kind, const Instruction *Inst);
/// getMDs - Get the metadata attached to an Instruction.
- void getMDs(const Instruction *Inst, SmallVectorImpl<MDPairTy> &MDs) const;
+ void getMDs(const Instruction *Inst,
+ SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const;
/// addMD - Attach the metadata of given kind to an Instruction.
void addMD(unsigned Kind, MDNode *Node, Instruction *Inst);
/// getMDs - Get the metadata attached to an Instruction.
void MetadataContextImpl::
-getMDs(const Instruction *Inst, SmallVectorImpl<MDPairTy> &MDs) const {
+getMDs(const Instruction *Inst,
+ SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const {
MDStoreTy::const_iterator I = MetadataStore.find(Inst);
if (I == MetadataStore.end())
return;
/// getMDs - Get the metadata attached to an Instruction.
void MetadataContext::
getMDs(const Instruction *Inst,
- SmallVectorImpl<std::pair<unsigned, TrackingVH<MDNode> > > &MDs) const {
+ SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const {
return pImpl->getMDs(Inst, MDs);
}