//===----------------------------------------------------------------------===//
#if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \
- defined HANDLE_METADATA_BRANCH)
+ defined HANDLE_METADATA_BRANCH || defined HANDLE_UNIQUABLE_LEAF || \
+ defined HANDLE_UNIQUABLE_BRANCH)
#error "Missing macro definition of HANDLE_METADATA*"
#endif
#define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS)
#endif
+// Handler for leaf nodes under UniquableMDNode.
+#ifndef HANDLE_UNIQUABLE_LEAF
+#define HANDLE_UNIQUABLE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS)
+#endif
+
+// Handler for non-leaf nodes under UniquableMDNode.
+#ifndef HANDLE_UNIQUABLE_BRANCH
+#define HANDLE_UNIQUABLE_BRANCH(CLASS) HANDLE_METADATA_BRANCH(CLASS)
+#endif
+
HANDLE_METADATA_LEAF(MDString)
HANDLE_METADATA_BRANCH(ValueAsMetadata)
HANDLE_METADATA_LEAF(ConstantAsMetadata)
HANDLE_METADATA_LEAF(LocalAsMetadata)
HANDLE_METADATA_BRANCH(MDNode)
HANDLE_METADATA_LEAF(MDNodeFwdDecl)
-HANDLE_METADATA_BRANCH(UniquableMDNode)
-HANDLE_METADATA_LEAF(MDTuple)
+HANDLE_UNIQUABLE_BRANCH(UniquableMDNode)
+HANDLE_UNIQUABLE_LEAF(MDTuple)
#undef HANDLE_METADATA
#undef HANDLE_METADATA_LEAF
#undef HANDLE_METADATA_BRANCH
+#undef HANDLE_UNIQUABLE_LEAF
+#undef HANDLE_UNIQUABLE_BRANCH
void resolve();
void resolveAfterOperandChange(Metadata *Old, Metadata *New);
void decrementUnresolvedOperandCount();
+
+ void deleteAsSubclass();
+ UniquableMDNode *uniquify();
+ void eraseFromStore();
};
/// \brief Tuple of metadata.
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTupleKind;
}
+
+private:
+ MDTuple *uniquifyImpl();
+ void eraseFromStoreImpl();
};
MDNode *MDNode::get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
return;
}
- auto &Store = getContext().pImpl->MDTuples;
- Store.erase(cast<MDTuple>(this));
+ // This node is uniqued.
+ eraseFromStore();
Metadata *Old = getOperand(Op);
setOperand(Op, New);
}
// Re-unique the node.
- cast<MDTuple>(this)->recalculateHash();
- MDTupleInfo::KeyTy Key(cast<MDTuple>(this));
- auto I = Store.find_as(Key);
- if (I == Store.end()) {
- Store.insert(cast<MDTuple>(this));
-
+ auto *Uniqued = uniquify();
+ if (Uniqued == this) {
if (!isResolved())
resolveAfterOperandChange(Old, New);
-
return;
}
// dropAllReferences(), but we still need the use-list).
for (unsigned O = 0, E = getNumOperands(); O != E; ++O)
setOperand(O, nullptr);
- ReplaceableUses->replaceAllUsesWith(*I);
- delete cast<MDTuple>(this);
+ ReplaceableUses->replaceAllUsesWith(Uniqued);
+ deleteAsSubclass();
return;
}
storeDistinctInContext();
}
+void UniquableMDNode::deleteAsSubclass() {
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid subclass of UniquableMDNode");
+#define HANDLE_UNIQUABLE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ delete cast<CLASS>(this); \
+ break;
+#include "llvm/IR/Metadata.def"
+ }
+}
+
+UniquableMDNode *UniquableMDNode::uniquify() {
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid subclass of UniquableMDNode");
+#define HANDLE_UNIQUABLE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ return cast<CLASS>(this)->uniquifyImpl();
+#include "llvm/IR/Metadata.def"
+ }
+}
+
+void UniquableMDNode::eraseFromStore() {
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid subclass of UniquableMDNode");
+#define HANDLE_UNIQUABLE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ cast<CLASS>(this)->eraseFromStoreImpl(); \
+ break;
+#include "llvm/IR/Metadata.def"
+ }
+}
+
MDTuple *MDTuple::getImpl(LLVMContext &Context, ArrayRef<Metadata *> MDs,
bool ShouldCreate) {
MDTupleInfo::KeyTy Key(MDs);
return N;
}
+MDTuple *MDTuple::uniquifyImpl() {
+ recalculateHash();
+ MDTupleInfo::KeyTy Key(this);
+
+ auto &Store = getContext().pImpl->MDTuples;
+ auto I = Store.find_as(Key);
+ if (I == Store.end()) {
+ Store.insert(this);
+ return this;
+ }
+ return *I;
+}
+
+void MDTuple::eraseFromStoreImpl() { getContext().pImpl->MDTuples.erase(this); }
+
MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context,
ArrayRef<Metadata *> MDs) {
return MDNodeFwdDecl::get(Context, MDs);