void operator=(const MDNode &); // DO NOT IMPLEMENT
friend class MDNodeElement;
- MDNodeElement *Operands;
+ /// NumOperands - This many 'MDNodeElement' items are co-allocated onto the
+ /// end of this MDNode.
unsigned NumOperands;
// Subclass data enums.
/// NotUniquedBit - This is set on MDNodes that are not uniqued because they
/// have a null perand.
- NotUniquedBit = 1 << 1
+ NotUniquedBit = 1 << 1,
+
+ /// DestroyFlag - This bit is set by destroy() so the destructor can assert
+ /// that the node isn't being destroyed with a plain 'delete'.
+ DestroyFlag = 1 << 2
};
// Replace each instance of F from the element list of this node with T.
void replaceElement(MDNodeElement *Op, Value *NewVal);
+ ~MDNode();
protected:
explicit MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
// Constructors and destructors.
static MDNode *get(LLVMContext &Context, Value *const *Vals, unsigned NumVals,
bool isFunctionLocal = false);
-
- /// ~MDNode - Destroy MDNode.
- ~MDNode();
/// getElement - Return specified element.
Value *getElement(unsigned i) const;
return (getSubclassDataFromValue() & FunctionLocalBit) != 0;
}
+ // destroy - Delete this node. Only when there are no uses.
+ void destroy();
+
/// Profile - calculate a unique identifier for this MDNode to collapse
/// duplicates
void Profile(FoldingSetNodeID &ID) const;
class MDNodeElement : public CallbackVH {
MDNode *Parent;
public:
- MDNodeElement() {}
MDNodeElement(Value *V, MDNode *P) : CallbackVH(V), Parent(P) {}
~MDNodeElement() {}
- void set(Value *V, MDNode *P) {
+ void set(Value *V) {
setValPtr(V);
- Parent = P;
}
virtual void deleted();
// MDNode implementation.
//
+/// getOperandPtr - Helper function to get the MDNodeElement's coallocated on
+/// the end of the MDNode.
+static MDNodeElement *getOperandPtr(MDNode *N, unsigned Op) {
+ assert(Op < N->getNumElements() && "Invalid operand number");
+ return reinterpret_cast<MDNodeElement*>(N+1)+Op;
+}
+
+MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
+ bool isFunctionLocal)
+: MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
+ NumOperands = NumVals;
+
+ if (isFunctionLocal)
+ setValueSubclassData(getSubclassDataFromValue() | FunctionLocalBit);
+
+ // Initialize the operand list, which is co-allocated on the end of the node.
+ for (MDNodeElement *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
+ Op != E; ++Op, ++Vals)
+ new (Op) MDNodeElement(*Vals, this);
+}
+
+
/// ~MDNode - Destroy MDNode.
MDNode::~MDNode() {
+ assert((getSubclassDataFromValue() & DestroyFlag) != 0 &&
+ "Not being destroyed through destroy()?");
if (!isNotUniqued()) {
LLVMContextImpl *pImpl = getType()->getContext().pImpl;
pImpl->MDNodeSet.RemoveNode(this);
}
- delete [] Operands;
- Operands = NULL;
+
+ // Destroy the operands.
+ for (MDNodeElement *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
+ Op != E; ++Op)
+ Op->~MDNodeElement();
}
-MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
- bool isFunctionLocal)
- : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
- NumOperands = NumVals;
- // FIXME: Coallocate the operand list. These have fixed arity.
- Operands = new MDNodeElement[NumOperands];
-
- for (unsigned i = 0; i != NumVals; ++i)
- Operands[i].set(Vals[i], this);
-
- if (isFunctionLocal)
- setValueSubclassData(getSubclassDataFromValue() | FunctionLocalBit);
+// destroy - Delete this node. Only when there are no uses.
+void MDNode::destroy() {
+ setValueSubclassData(getSubclassDataFromValue() | DestroyFlag);
+ // Placement delete, the free the memory.
+ this->~MDNode();
+ free(this);
}
+
MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals,
bool isFunctionLocal) {
LLVMContextImpl *pImpl = Context.pImpl;
void *InsertPoint;
MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
if (!N) {
+ // Coallocate space for the node and elements together, then placement new.
+ void *Ptr = malloc(sizeof(MDNode)+NumVals*sizeof(MDNodeElement));
+ N = new (Ptr) MDNode(Context, Vals, NumVals, isFunctionLocal);
+
// InsertPoint will have been set by the FindNodeOrInsertPos call.
- N = new MDNode(Context, Vals, NumVals, isFunctionLocal);
pImpl->MDNodeSet.InsertNode(N, InsertPoint);
}
return N;
}
-void MDNode::Profile(FoldingSetNodeID &ID) const {
- for (unsigned i = 0, e = getNumElements(); i != e; ++i)
- ID.AddPointer(getElement(i));
- // HASH TABLE COLLISIONS?
- // DO NOT REINSERT AFTER AN OPERAND DROPS TO NULL!
-}
-
-
/// getElement - Return specified element.
Value *MDNode::getElement(unsigned i) const {
- assert(i < getNumElements() && "Invalid element number!");
- return Operands[i];
+ return *getOperandPtr(const_cast<MDNode*>(this), i);
}
+void MDNode::Profile(FoldingSetNodeID &ID) const {
+ for (unsigned i = 0, e = getNumElements(); i != e; ++i)
+ ID.AddPointer(getElement(i));
+}
// Replace value from this node's element list.
return;
// Update the operand.
- Op->set(To, this);
+ Op->set(To);
// If this node is already not being uniqued (because one of the operands
// already went to null), then there is nothing else to do here.
MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
if (N) {
- // FIXME:
- // If it already exists in the set, we don't reinsert it, we just claim it
- // isn't uniqued.
-
N->replaceAllUsesWith(this);
- delete N;
+ N->destroy();
N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
assert(N == 0 && "shouldn't be in the map now!"); (void)N;
}
//===----------------------------------------------------------------------===//
-// MetadataContext implementation.
+// LLVMContext MDKind naming implementation.
//
#ifndef NDEBUG