#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Value.h"
+#include "llvm/Support/ErrorHandling.h"
namespace llvm {
class LLVMContext;
void operator=(const MDNode &) LLVM_DELETED_FUNCTION;
friend class MDNodeOperand;
friend class LLVMContextImpl;
+ void *operator new(size_t) LLVM_DELETED_FUNCTION;
protected:
+ void *operator new(size_t Size, unsigned NumOps);
+
+ /// \brief Required by std, but never called.
+ void operator delete(void *Mem);
+
+ /// \brief Required by std, but never called.
+ void operator delete(void *, unsigned) {
+ llvm_unreachable("Constructor throws?");
+ }
+
+ /// \brief Required by std, but never called.
+ void operator delete(void *, unsigned, bool) {
+ llvm_unreachable("Constructor throws?");
+ }
+
// TODO: Sink this into GenericMDNode. Can't do this until operands are
// allocated at the front (currently they're at the back).
unsigned Hash;
/// NotUniquedBit - This is set on MDNodes that are not uniqued because they
/// have a null operand.
- 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
+ NotUniquedBit = 1 << 1
};
/// \brief FunctionLocal enums.
/// \brief Replace each instance of the given operand with a new value.
void replaceOperand(MDNodeOperand *Op, Value *NewVal);
- ~MDNode();
MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,
bool isFunctionLocal);
+ ~MDNode() {}
static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,
FunctionLocalness FL, bool Insert = true);
/// TODO: Drop support for RAUW.
class GenericMDNode : public MDNode {
friend class MDNode;
+ friend class LLVMContextImpl;
GenericMDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)
: MDNode(C, GenericMDNodeVal, Vals, isFunctionLocal) {}
~GenericMDNode();
+ void dropAllReferences();
+
public:
/// \brief Get the hash, if any.
unsigned getHash() const { return Hash; }
static bool classof(const Value *V) {
return V->getValueID() == GenericMDNodeVal;
}
-
-private:
- /// \brief Delete this node. Only when there are no uses.
- void destroy();
- friend class MDNode;
- friend class LLVMContextImpl;
};
/// \brief Forward declaration of metadata.
static bool classof(const Value *V) {
return V->getValueID() == MDNodeFwdDeclVal;
}
-
-private:
- /// \brief Delete this node. Only when there are no uses.
- void destroy();
- friend class MDNode;
};
//===----------------------------------------------------------------------===//
MDNodeOperand *Cur = this;
while (Cur->getValPtrInt() != 1)
- --Cur;
+ ++Cur;
assert(Cur->getValPtrInt() == 1 &&
- "Couldn't find the beginning of the operand list!");
- return reinterpret_cast<MDNode*>(Cur) - 1;
+ "Couldn't find the end of the operand list!");
+ return reinterpret_cast<MDNode *>(Cur + 1);
}
public:
- MDNodeOperand(Value *V) : CallbackVH(V) {}
+ MDNodeOperand() {}
virtual ~MDNodeOperand();
void set(Value *V) {
- unsigned IsFirst = this->getValPtrInt();
+ unsigned IsLast = this->getValPtrInt();
this->setValPtr(V);
- this->setAsFirstOperand(IsFirst);
+ this->setAsLastOperand(IsLast);
}
/// \brief Accessor method to mark the operand as the first in the list.
- void setAsFirstOperand(unsigned V) { this->setValPtrInt(V); }
+ void setAsLastOperand(unsigned I) { this->setValPtrInt(I); }
void deleted() override;
void allUsesReplacedWith(Value *NV) override;
/// \brief Get the MDNodeOperand's coallocated on the end of the MDNode.
static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) {
- static_assert(sizeof(GenericMDNode) == sizeof(MDNode),
- "Expected subclasses to have no size overhead");
- static_assert(sizeof(MDNodeFwdDecl) == sizeof(MDNode),
- "Expected subclasses to have no size overhead");
-
// Use <= instead of < to permit a one-past-the-end address.
assert(Op <= N->getNumOperands() && "Invalid operand number");
- return reinterpret_cast<MDNodeOperand*>(N + 1) + Op;
+ return reinterpret_cast<MDNodeOperand *>(N) - N->getNumOperands() + Op;
}
void MDNode::replaceOperandWith(unsigned i, Value *Val) {
replaceOperand(Op, Val);
}
+void *MDNode::operator new(size_t Size, unsigned NumOps) {
+ void *Ptr = ::operator new(Size + NumOps * sizeof(MDNodeOperand));
+ MDNodeOperand *Op = static_cast<MDNodeOperand *>(Ptr);
+ if (NumOps) {
+ MDNodeOperand *Last = Op + NumOps;
+ for (; Op != Last; ++Op)
+ new (Op) MDNodeOperand();
+ (Op - 1)->setAsLastOperand(1);
+ }
+ return Op;
+}
+
+void MDNode::operator delete(void *Mem) {
+ MDNode *N = static_cast<MDNode *>(Mem);
+ MDNodeOperand *Op = static_cast<MDNodeOperand *>(Mem);
+ for (unsigned I = 0, E = N->NumOperands; I != E; ++I)
+ (--Op)->~MDNodeOperand();
+ ::operator delete(Op);
+}
+
MDNode::MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,
bool isFunctionLocal)
: Metadata(C, ID), Hash(0) {
if (isFunctionLocal)
setValueSubclassData(getSubclassDataFromValue() | FunctionLocalBit);
- // Initialize the operand list, which is co-allocated on the end of the node.
+ // Initialize the operand list.
unsigned i = 0;
- for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
- Op != E; ++Op, ++i) {
- new (Op) MDNodeOperand(Vals[i]);
-
- // Mark the first MDNodeOperand as being the first in the list of operands.
- if (i == 0)
- Op->setAsFirstOperand(1);
- }
+ for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op + NumOperands;
+ Op != E; ++Op, ++i)
+ Op->set(Vals[i]);
}
GenericMDNode::~GenericMDNode() {
}
}
-MDNode::~MDNode() {
- assert((getSubclassDataFromValue() & DestroyFlag) != 0 &&
- "Not being destroyed through destroy()?");
-
- // Destroy the operands.
- for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
+void GenericMDNode::dropAllReferences() {
+ for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op + NumOperands;
Op != E; ++Op)
- Op->~MDNodeOperand();
+ Op->set(nullptr);
}
static const Function *getFunctionForValue(Value *V) {
#endif
}
-// destroy - Delete this node. Only when there are no uses.
-void GenericMDNode::destroy() {
- setValueSubclassData(getSubclassDataFromValue() | DestroyFlag);
- // Placement delete, then free the memory.
- this->~GenericMDNode();
- free(this);
-}
-
-void MDNodeFwdDecl::destroy() {
- setValueSubclassData(getSubclassDataFromValue() | DestroyFlag);
- // Placement delete, then free the memory.
- this->~MDNodeFwdDecl();
- free(this);
-}
-
/// \brief Check if the Value would require a function-local MDNode.
static bool isFunctionLocalValue(Value *V) {
return isa<Instruction>(V) || isa<Argument>(V) || isa<BasicBlock>(V) ||
}
// Coallocate space for the node and Operands together, then placement new.
- void *Ptr =
- malloc(sizeof(GenericMDNode) + Vals.size() * sizeof(MDNodeOperand));
- GenericMDNode *N = new (Ptr) GenericMDNode(Context, Vals, isFunctionLocal);
+ GenericMDNode *N =
+ new (Vals.size()) GenericMDNode(Context, Vals, isFunctionLocal);
N->Hash = Key.Hash;
Store.insert(N);
}
MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals) {
- MDNode *N = (MDNode *)malloc(sizeof(MDNodeFwdDecl) +
- Vals.size() * sizeof(MDNodeOperand));
- N = new (N) MDNodeFwdDecl(Context, Vals, FL_No);
- N->setValueSubclassData(N->getSubclassDataFromValue() |
- NotUniquedBit);
+ MDNode *N = new (Vals.size()) MDNodeFwdDecl(Context, Vals, FL_No);
+ N->setValueSubclassData(N->getSubclassDataFromValue() | NotUniquedBit);
LeakDetector::addGarbageObject(N);
return N;
}
assert(isa<MDNodeFwdDecl>(N) && "Expected forward declaration");
assert((N->getSubclassDataFromValue() & NotUniquedBit) &&
"Temporary MDNode does not have NotUniquedBit set!");
- assert((N->getSubclassDataFromValue() & DestroyFlag) == 0 &&
- "Temporary MDNode has DestroyFlag set!");
LeakDetector::removeGarbageObject(N);
- cast<MDNodeFwdDecl>(N)->destroy();
+ delete cast<MDNodeFwdDecl>(N);
}
/// \brief Return specified operand.
auto I = Store.find_as(Key);
if (I != Store.end()) {
N->replaceAllUsesWith(*I);
- N->destroy();
+ delete N;
return;
}