IR: Prepare for a new UniquableMDNode subclass, NFC

Add generic dispatch for the parts of `UniquableMDNode` that cast to
`MDTuple`.  This makes adding other subclasses (like PR21433's
`MDLocation`) easier.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225697 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-01-12 20:56:33 +00:00
parent d1ec4f037d
commit 343bb3e252
4 changed files with 81 additions and 15 deletions

View File

@ -12,7 +12,8 @@
//===----------------------------------------------------------------------===//
#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
@ -31,15 +32,27 @@
#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

View File

@ -755,6 +755,10 @@ private:
void resolve();
void resolveAfterOperandChange(Metadata *Old, Metadata *New);
void decrementUnresolvedOperandCount();
void deleteAsSubclass();
UniquableMDNode *uniquify();
void eraseFromStore();
};
/// \brief Tuple of metadata.
@ -794,6 +798,10 @@ public:
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTupleKind;
}
private:
MDTuple *uniquifyImpl();
void eraseFromStoreImpl();
};
MDNode *MDNode::get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {

View File

@ -142,7 +142,7 @@ LLVMContextImpl::~LLVMContextImpl() {
I->dropAllReferences();
for (UniquableMDNode *I : DistinctMDNodes)
delete cast<MDTuple>(I);
I->deleteAsSubclass();
for (MDTuple *I : MDTuples)
delete I;

View File

@ -525,8 +525,8 @@ void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {
return;
}
auto &Store = getContext().pImpl->MDTuples;
Store.erase(cast<MDTuple>(this));
// This node is uniqued.
eraseFromStore();
Metadata *Old = getOperand(Op);
setOperand(Op, New);
@ -540,15 +540,10 @@ void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *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;
}
@ -560,8 +555,8 @@ void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {
// 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;
}
@ -569,6 +564,41 @@ void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {
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);
@ -593,6 +623,21 @@ MDTuple *MDTuple::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> 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);