[llvm] r222205 - IR: Split MDNode into GenericMDNode and MDNodeFwdDecl
Duncan P. N. Exon Smith
dexonsmith at apple.com
Mon Nov 17 16:37:18 PST 2014
Author: dexonsmith
Date: Mon Nov 17 18:37:17 2014
New Revision: 222205
URL: http://llvm.org/viewvc/llvm-project?rev=222205&view=rev
Log:
IR: Split MDNode into GenericMDNode and MDNodeFwdDecl
Split `MDNode` into two classes:
- `GenericMDNode`, which is uniquable (and for now, always starts
uniqued). Once `Metadata` is split from the `Value` hierarchy, this
class will lose the ability to RAUW itself.
- `MDNodeFwdDecl`, which is used for the "temporary" interface, is
never uniqued, and isn't managed by `LLVMContext` at all.
I've left most of the guts in `MDNode` for now, but I'll incrementally
move things to the right places (or delete the functionality, as
appropriate).
Part of PR21532.
Modified:
llvm/trunk/include/llvm/IR/Metadata.h
llvm/trunk/include/llvm/IR/Value.h
llvm/trunk/lib/IR/LLVMContextImpl.cpp
llvm/trunk/lib/IR/LLVMContextImpl.h
llvm/trunk/lib/IR/Metadata.cpp
Modified: llvm/trunk/include/llvm/IR/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=222205&r1=222204&r2=222205&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.h (original)
+++ llvm/trunk/include/llvm/IR/Metadata.h Mon Nov 17 18:37:17 2014
@@ -45,7 +45,9 @@ protected:
public:
static bool classof(const Value *V) {
- return V->getValueID() == MDNodeVal || V->getValueID() == MDStringVal;
+ return V->getValueID() == GenericMDNodeVal ||
+ V->getValueID() == MDNodeFwdDeclVal ||
+ V->getValueID() == MDStringVal;
}
};
@@ -137,14 +139,16 @@ struct DenseMapInfo<AAMDNodes> {
class MDNodeOperand;
//===----------------------------------------------------------------------===//
-/// \brief Generic tuple of metadata.
+/// \brief Tuple of metadata.
class MDNode : public Metadata {
MDNode(const MDNode &) LLVM_DELETED_FUNCTION;
void operator=(const MDNode &) LLVM_DELETED_FUNCTION;
friend class MDNodeOperand;
friend class LLVMContextImpl;
- /// \brief If the MDNode is uniqued cache the hash to speed up lookup.
+protected:
+ // TODO: Sink this into GenericMDNode. Can't do this until operands are
+ // allocated at the front (currently they're at the back).
unsigned Hash;
/// \brief Subclass data enums.
@@ -174,7 +178,8 @@ class MDNode : public Metadata {
void replaceOperand(MDNodeOperand *Op, Value *NewVal);
~MDNode();
- MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal);
+ MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,
+ bool isFunctionLocal);
static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,
FunctionLocalness FL, bool Insert = true);
@@ -223,12 +228,10 @@ public:
/// code because it recursively visits all the MDNode's operands.
const Function *getFunction() const;
- /// \brief Get the hash, if any.
- unsigned getHash() const { return Hash; }
-
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
- return V->getValueID() == MDNodeVal;
+ return V->getValueID() == GenericMDNodeVal ||
+ V->getValueID() == MDNodeFwdDeclVal;
}
/// \brief Check whether MDNode is a vtable access.
@@ -241,10 +244,8 @@ public:
static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B);
static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
-private:
- /// \brief Delete this node. Only when there are no uses.
- void destroy();
+protected:
bool isNotUniqued() const {
return (getSubclassDataFromValue() & NotUniquedBit) != 0;
}
@@ -257,6 +258,61 @@ private:
}
};
+/// \brief Generic metadata node.
+///
+/// Generic metadata nodes, with opt-out support for uniquing.
+///
+/// Although nodes are uniqued by default, \a GenericMDNode has no support for
+/// RAUW. If an operand change (due to RAUW or otherwise) causes a uniquing
+/// collision, the uniquing bit is dropped.
+///
+/// TODO: Make uniquing opt-out (status: mandatory, sometimes dropped).
+/// TODO: Drop support for RAUW.
+class GenericMDNode : public MDNode {
+ friend class MDNode;
+
+ GenericMDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)
+ : MDNode(C, GenericMDNodeVal, Vals, isFunctionLocal) {}
+ ~GenericMDNode();
+
+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.
+///
+/// Forward declaration of metadata, in the form of a metadata node. Unlike \a
+/// GenericMDNode, this class has support for RAUW and is suitable for forward
+/// references.
+class MDNodeFwdDecl : public MDNode {
+ friend class MDNode;
+
+ MDNodeFwdDecl(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)
+ : MDNode(C, MDNodeFwdDeclVal, Vals, isFunctionLocal) {}
+ ~MDNodeFwdDecl() {}
+
+public:
+ 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;
+};
+
//===----------------------------------------------------------------------===//
/// \brief A tuple of MDNodes.
///
Modified: llvm/trunk/include/llvm/IR/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.h?rev=222205&r1=222204&r2=222205&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Value.h (original)
+++ llvm/trunk/include/llvm/IR/Value.h Mon Nov 17 18:37:17 2014
@@ -345,7 +345,8 @@ public:
ConstantStructVal, // This is an instance of ConstantStruct
ConstantVectorVal, // This is an instance of ConstantVector
ConstantPointerNullVal, // This is an instance of ConstantPointerNull
- MDNodeVal, // This is an instance of MDNode
+ GenericMDNodeVal, // This is an instance of GenericMDNode
+ MDNodeFwdDeclVal, // This is an instance of MDNodeFwdDecl
MDStringVal, // This is an instance of MDString
InlineAsmVal, // This is an instance of InlineAsm
InstructionVal, // This is an instance of Instruction
@@ -681,7 +682,8 @@ template <> struct isa_impl<GlobalObject
template <> struct isa_impl<MDNode, Value> {
static inline bool doit(const Value &Val) {
- return Val.getValueID() == Value::MDNodeVal;
+ return Val.getValueID() == Value::GenericMDNodeVal ||
+ Val.getValueID() == Value::MDNodeFwdDeclVal;
}
};
Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=222205&r1=222204&r2=222205&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Mon Nov 17 18:37:17 2014
@@ -122,13 +122,12 @@ LLVMContextImpl::~LLVMContextImpl() {
// Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet
// and the NonUniquedMDNodes sets, so copy the values out first.
- SmallVector<MDNode*, 8> MDNodes;
+ SmallVector<GenericMDNode *, 8> MDNodes;
MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size());
MDNodes.append(MDNodeSet.begin(), MDNodeSet.end());
MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end());
- for (SmallVectorImpl<MDNode *>::iterator I = MDNodes.begin(),
- E = MDNodes.end(); I != E; ++I)
- (*I)->destroy();
+ for (auto &I : MDNodes)
+ I->destroy();
assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() &&
"Destroying all MDNodes didn't empty the Context's sets.");
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=222205&r1=222204&r2=222205&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Mon Nov 17 18:37:17 2014
@@ -191,7 +191,7 @@ struct FunctionTypeKeyInfo {
}
};
-/// \brief DenseMapInfo for MDNode.
+/// \brief DenseMapInfo for GenericMDNode.
///
/// Note that we don't need the is-function-local bit, since that's implicit in
/// the operands.
@@ -203,7 +203,7 @@ struct GenericMDNodeInfo {
KeyTy(ArrayRef<Value *> Ops)
: Ops(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
- KeyTy(MDNode *N, SmallVectorImpl<Value *> &Storage) {
+ KeyTy(GenericMDNode *N, SmallVectorImpl<Value *> &Storage) {
Storage.resize(N->getNumOperands());
for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I)
Storage[I] = N->getOperand(I);
@@ -211,7 +211,7 @@ struct GenericMDNodeInfo {
Hash = hash_combine_range(Ops.begin(), Ops.end());
}
- bool operator==(const MDNode *RHS) const {
+ bool operator==(const GenericMDNode *RHS) const {
if (RHS == getEmptyKey() || RHS == getTombstoneKey())
return false;
if (Hash != RHS->getHash() || Ops.size() != RHS->getNumOperands())
@@ -222,20 +222,20 @@ struct GenericMDNodeInfo {
return true;
}
};
- static inline MDNode *getEmptyKey() {
- return DenseMapInfo<MDNode *>::getEmptyKey();
+ static inline GenericMDNode *getEmptyKey() {
+ return DenseMapInfo<GenericMDNode *>::getEmptyKey();
}
- static inline MDNode *getTombstoneKey() {
- return DenseMapInfo<MDNode *>::getTombstoneKey();
+ static inline GenericMDNode *getTombstoneKey() {
+ return DenseMapInfo<GenericMDNode *>::getTombstoneKey();
}
static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; }
- static unsigned getHashValue(const MDNode *U) {
+ static unsigned getHashValue(const GenericMDNode *U) {
return U->getHash();
}
- static bool isEqual(const KeyTy &LHS, const MDNode *RHS) {
+ static bool isEqual(const KeyTy &LHS, const GenericMDNode *RHS) {
return LHS == RHS;
}
- static bool isEqual(const MDNode *LHS, const MDNode *RHS) {
+ static bool isEqual(const GenericMDNode *LHS, const GenericMDNode *RHS) {
return LHS == RHS;
}
};
@@ -293,14 +293,14 @@ public:
StringMap<MDString> MDStringCache;
- DenseSet<MDNode *, GenericMDNodeInfo> MDNodeSet;
+ DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet;
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they
// aren't in the MDNodeSet, but they're still shared between objects, so no
// one object can destroy them. This set allows us to at least destroy them
// on Context destruction.
- SmallPtrSet<MDNode*, 1> NonUniquedMDNodes;
-
+ SmallPtrSet<GenericMDNode *, 1> NonUniquedMDNodes;
+
DenseMap<Type*, ConstantAggregateZero*> CAZConstants;
typedef ConstantUniqueMap<ConstantArray> ArrayConstantsTy;
Modified: llvm/trunk/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=222205&r1=222204&r2=222205&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Metadata.cpp (original)
+++ llvm/trunk/lib/IR/Metadata.cpp Mon Nov 17 18:37:17 2014
@@ -108,6 +108,11 @@ void MDNodeOperand::allUsesReplacedWith(
/// \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;
@@ -118,8 +123,9 @@ void MDNode::replaceOperandWith(unsigned
replaceOperand(Op, Val);
}
-MDNode::MDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)
- : Metadata(C, Value::MDNodeVal), Hash(0) {
+MDNode::MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,
+ bool isFunctionLocal)
+ : Metadata(C, ID), Hash(0) {
NumOperands = Vals.size();
if (isFunctionLocal)
@@ -137,16 +143,18 @@ MDNode::MDNode(LLVMContext &C, ArrayRef<
}
}
-/// ~MDNode - Destroy MDNode.
-MDNode::~MDNode() {
- assert((getSubclassDataFromValue() & DestroyFlag) != 0 &&
- "Not being destroyed through destroy()?");
+GenericMDNode::~GenericMDNode() {
LLVMContextImpl *pImpl = getType()->getContext().pImpl;
if (isNotUniqued()) {
pImpl->NonUniquedMDNodes.erase(this);
} else {
pImpl->MDNodeSet.erase(this);
}
+}
+
+MDNode::~MDNode() {
+ assert((getSubclassDataFromValue() & DestroyFlag) != 0 &&
+ "Not being destroyed through destroy()?");
// Destroy the operands.
for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;
@@ -209,10 +217,17 @@ const Function *MDNode::getFunction() co
}
// destroy - Delete this node. Only when there are no uses.
-void MDNode::destroy() {
+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->~MDNode();
+ this->~MDNodeFwdDecl();
free(this);
}
@@ -253,8 +268,9 @@ MDNode *MDNode::getMDNode(LLVMContext &C
}
// Coallocate space for the node and Operands together, then placement new.
- void *Ptr = malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand));
- MDNode *N = new (Ptr) MDNode(Context, Vals, isFunctionLocal);
+ void *Ptr =
+ malloc(sizeof(GenericMDNode) + Vals.size() * sizeof(MDNodeOperand));
+ GenericMDNode *N = new (Ptr) GenericMDNode(Context, Vals, isFunctionLocal);
N->Hash = Key.Hash;
Store.insert(N);
@@ -276,9 +292,9 @@ MDNode *MDNode::getIfExists(LLVMContext
}
MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals) {
- MDNode *N =
- (MDNode *)malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand));
- N = new (N) MDNode(Context, Vals, FL_No);
+ MDNode *N = (MDNode *)malloc(sizeof(MDNodeFwdDecl) +
+ Vals.size() * sizeof(MDNodeOperand));
+ N = new (N) MDNodeFwdDecl(Context, Vals, FL_No);
N->setValueSubclassData(N->getSubclassDataFromValue() |
NotUniquedBit);
LeakDetector::addGarbageObject(N);
@@ -287,16 +303,13 @@ MDNode *MDNode::getTemporary(LLVMContext
void MDNode::deleteTemporary(MDNode *N) {
assert(N->use_empty() && "Temporary MDNode has uses!");
- assert(!N->getContext().pImpl->MDNodeSet.erase(N) &&
- "Deleting a non-temporary uniqued node!");
- assert(!N->getContext().pImpl->NonUniquedMDNodes.erase(N) &&
- "Deleting a non-temporary non-uniqued node!");
+ 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);
- N->destroy();
+ cast<MDNodeFwdDecl>(N)->destroy();
}
/// \brief Return specified operand.
@@ -308,8 +321,9 @@ Value *MDNode::getOperand(unsigned i) co
void MDNode::setIsNotUniqued() {
setValueSubclassData(getSubclassDataFromValue() | NotUniquedBit);
LLVMContextImpl *pImpl = getType()->getContext().pImpl;
- Hash = 0;
- pImpl->NonUniquedMDNodes.insert(this);
+ auto *G = cast<GenericMDNode>(this);
+ G->Hash = 0;
+ pImpl->NonUniquedMDNodes.insert(G);
}
// Replace value from this node's operand list.
@@ -345,9 +359,10 @@ void MDNode::replaceOperand(MDNodeOperan
}
auto &Store = getContext().pImpl->MDNodeSet;
+ auto *N = cast<GenericMDNode>(this);
// Remove "this" from the context map.
- Store.erase(this);
+ Store.erase(N);
// Update the operand.
Op->set(To);
@@ -365,16 +380,16 @@ void MDNode::replaceOperand(MDNodeOperan
// check to see if another node with the same operands already exists in the
// set. If so, then this node is redundant.
SmallVector<Value *, 8> Vals;
- GenericMDNodeInfo::KeyTy Key(this, Vals);
+ GenericMDNodeInfo::KeyTy Key(N, Vals);
auto I = Store.find_as(Key);
if (I != Store.end()) {
- replaceAllUsesWith(*I);
- destroy();
+ N->replaceAllUsesWith(*I);
+ N->destroy();
return;
}
- this->Hash = Key.Hash;
- Store.insert(this);
+ N->Hash = Key.Hash;
+ Store.insert(N);
// If this MDValue was previously function-local but no longer is, clear
// its function-local flag.
More information about the llvm-commits
mailing list