IR: Merge UniquableMDNode back into MDNode, NFC

As pointed out in r226501, the distinction between `MDNode` and
`UniquableMDNode` is confusing.  When we need subclasses of `MDNode`
that don't use all its functionality it might make sense to break it
apart again, but until then this makes the code clearer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226520 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2015-01-19 23:13:14 +00:00
parent fce53dd939
commit b0617860b5
10 changed files with 142 additions and 175 deletions

View File

@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \ #if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \
defined HANDLE_METADATA_BRANCH || defined HANDLE_UNIQUABLE_LEAF || \ defined HANDLE_METADATA_BRANCH || defined HANDLE_MDNODE_LEAF || \
defined HANDLE_UNIQUABLE_BRANCH) defined HANDLE_MDNODE_BRANCH)
#error "Missing macro definition of HANDLE_METADATA*" #error "Missing macro definition of HANDLE_METADATA*"
#endif #endif
@ -32,27 +32,26 @@
#define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS) #define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS)
#endif #endif
// Handler for leaf nodes under UniquableMDNode. // Handler for leaf nodes under MDNode.
#ifndef HANDLE_UNIQUABLE_LEAF #ifndef HANDLE_MDNODE_LEAF
#define HANDLE_UNIQUABLE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS) #define HANDLE_MDNODE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS)
#endif #endif
// Handler for non-leaf nodes under UniquableMDNode. // Handler for non-leaf nodes under MDNode.
#ifndef HANDLE_UNIQUABLE_BRANCH #ifndef HANDLE_MDNODE_BRANCH
#define HANDLE_UNIQUABLE_BRANCH(CLASS) HANDLE_METADATA_BRANCH(CLASS) #define HANDLE_MDNODE_BRANCH(CLASS) HANDLE_METADATA_BRANCH(CLASS)
#endif #endif
HANDLE_METADATA_LEAF(MDString) HANDLE_METADATA_LEAF(MDString)
HANDLE_METADATA_BRANCH(ValueAsMetadata) HANDLE_METADATA_BRANCH(ValueAsMetadata)
HANDLE_METADATA_LEAF(ConstantAsMetadata) HANDLE_METADATA_LEAF(ConstantAsMetadata)
HANDLE_METADATA_LEAF(LocalAsMetadata) HANDLE_METADATA_LEAF(LocalAsMetadata)
HANDLE_METADATA_BRANCH(MDNode) HANDLE_MDNODE_BRANCH(MDNode)
HANDLE_UNIQUABLE_BRANCH(UniquableMDNode) HANDLE_MDNODE_LEAF(MDTuple)
HANDLE_UNIQUABLE_LEAF(MDTuple) HANDLE_MDNODE_LEAF(MDLocation)
HANDLE_UNIQUABLE_LEAF(MDLocation)
#undef HANDLE_METADATA #undef HANDLE_METADATA
#undef HANDLE_METADATA_LEAF #undef HANDLE_METADATA_LEAF
#undef HANDLE_METADATA_BRANCH #undef HANDLE_METADATA_BRANCH
#undef HANDLE_UNIQUABLE_LEAF #undef HANDLE_MDNODE_LEAF
#undef HANDLE_UNIQUABLE_BRANCH #undef HANDLE_MDNODE_BRANCH

View File

@ -165,8 +165,8 @@ public:
/// \brief Resolve all uses of this. /// \brief Resolve all uses of this.
/// ///
/// Resolve all uses of this, turning off RAUW permanently. If \c /// Resolve all uses of this, turning off RAUW permanently. If \c
/// ResolveUsers, call \a UniquableMDNode::resolve() on any users whose last /// ResolveUsers, call \a MDNode::resolve() on any users whose last operand
/// operand is resolved. /// is resolved.
void resolveAllUses(bool ResolveUsers = true); void resolveAllUses(bool ResolveUsers = true);
private: private:
@ -655,15 +655,30 @@ struct TempMDNodeDeleter {
inline void operator()(MDNode *Node) const; inline void operator()(MDNode *Node) const;
}; };
#define HANDLE_UNIQUABLE_LEAF(CLASS) \ #define HANDLE_MDNODE_LEAF(CLASS) \
typedef std::unique_ptr<CLASS, TempMDNodeDeleter> Temp##CLASS; typedef std::unique_ptr<CLASS, TempMDNodeDeleter> Temp##CLASS;
#define HANDLE_UNIQUABLE_BRANCH(CLASS) HANDLE_UNIQUABLE_LEAF(CLASS) #define HANDLE_MDNODE_BRANCH(CLASS) HANDLE_MDNODE_LEAF(CLASS)
#include "llvm/IR/Metadata.def" #include "llvm/IR/Metadata.def"
//===----------------------------------------------------------------------===// /// \brief Metadata node.
/// \brief Tuple of metadata. ///
/// Metadata nodes can be uniqued, like constants, or distinct. Temporary
/// metadata nodes (with full support for RAUW) can be used to delay uniquing
/// until forward references are known. The basic metadata node is an \a
/// MDTuple.
///
/// There is limited support for RAUW at construction time. At construction
/// time, if any operand is a temporary node (or an unresolved uniqued node,
/// which indicates a transitive temporary operand), the node itself will be
/// unresolved. As soon as all operands become resolved, it will drop RAUW
/// support permanently.
///
/// If an unresolved node is part of a cycle, \a resolveCycles() needs
/// to be called on some member of the cycle once all temporary nodes have been
/// replaced.
class MDNode : public Metadata { class MDNode : public Metadata {
friend class ReplaceableMetadataImpl; friend class ReplaceableMetadataImpl;
friend class LLVMContextImpl;
MDNode(const MDNode &) LLVM_DELETED_FUNCTION; MDNode(const MDNode &) LLVM_DELETED_FUNCTION;
void operator=(const MDNode &) LLVM_DELETED_FUNCTION; void operator=(const MDNode &) LLVM_DELETED_FUNCTION;
@ -745,13 +760,20 @@ public:
Context.getReplaceableUses()->replaceAllUsesWith(MD); Context.getReplaceableUses()->replaceAllUsesWith(MD);
} }
/// \brief Resolve cycles.
///
/// Once all forward declarations have been resolved, force cycles to be
/// resolved.
///
/// \pre No operands (or operands' operands, etc.) have \a isTemporary().
void resolveCycles();
/// \brief Replace a temporary node with a uniqued one. /// \brief Replace a temporary node with a uniqued one.
/// ///
/// Create a uniqued version of \c N -- in place, if possible -- and return /// Create a uniqued version of \c N -- in place, if possible -- and return
/// it. Takes ownership of the temporary node. /// it. Takes ownership of the temporary node.
template <class T> template <class T>
static typename std::enable_if<std::is_base_of<UniquableMDNode, T>::value, static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
T *>::type
replaceWithUniqued(std::unique_ptr<T, TempMDNodeDeleter> N); replaceWithUniqued(std::unique_ptr<T, TempMDNodeDeleter> N);
/// \brief Replace a temporary node with a distinct one. /// \brief Replace a temporary node with a distinct one.
@ -759,8 +781,7 @@ public:
/// Create a distinct version of \c N -- in place, if possible -- and return /// Create a distinct version of \c N -- in place, if possible -- and return
/// it. Takes ownership of the temporary node. /// it. Takes ownership of the temporary node.
template <class T> template <class T>
static typename std::enable_if<std::is_base_of<UniquableMDNode, T>::value, static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
T *>::type
replaceWithDistinct(std::unique_ptr<T, TempMDNodeDeleter> N); replaceWithDistinct(std::unique_ptr<T, TempMDNodeDeleter> N);
protected: protected:
@ -769,6 +790,35 @@ protected:
/// Sets the operand directly, without worrying about uniquing. /// Sets the operand directly, without worrying about uniquing.
void setOperand(unsigned I, Metadata *New); void setOperand(unsigned I, Metadata *New);
void storeDistinctInContext();
template <class T, class StoreT>
static T *storeImpl(T *N, StorageType Storage, StoreT &Store);
private:
void handleChangedOperand(void *Ref, Metadata *New);
void resolve();
void resolveAfterOperandChange(Metadata *Old, Metadata *New);
void decrementUnresolvedOperandCount();
unsigned countUnresolvedOperands() const;
/// \brief Mutate this to be "uniqued".
///
/// Mutate this so that \a isUniqued().
/// \pre \a isTemporary().
/// \pre already added to uniquing set.
void makeUniqued();
/// \brief Mutate this to be "distinct".
///
/// Mutate this so that \a isDistinct().
/// \pre \a isTemporary().
void makeDistinct();
void deleteAsSubclass();
MDNode *uniquify();
void eraseFromStore();
public: public:
typedef const MDOperand *op_iterator; typedef const MDOperand *op_iterator;
typedef iterator_range<op_iterator> op_range; typedef iterator_range<op_iterator> op_range;
@ -807,11 +857,10 @@ public:
}; };
template <class NodeTy> template <class NodeTy>
typename std::enable_if<std::is_base_of<UniquableMDNode, NodeTy>::value, typename std::enable_if<std::is_base_of<MDNode, NodeTy>::value, NodeTy *>::type
NodeTy *>::type
MDNode::replaceWithUniqued(std::unique_ptr<NodeTy, TempMDNodeDeleter> Node) { MDNode::replaceWithUniqued(std::unique_ptr<NodeTy, TempMDNodeDeleter> Node) {
// Try to uniquify in place. // Try to uniquify in place.
UniquableMDNode *UniquedNode = Node->uniquify(); MDNode *UniquedNode = Node->uniquify();
if (UniquedNode == Node.get()) { if (UniquedNode == Node.get()) {
Node->makeUniqued(); Node->makeUniqued();
return Node.release(); return Node.release();
@ -823,98 +872,23 @@ MDNode::replaceWithUniqued(std::unique_ptr<NodeTy, TempMDNodeDeleter> Node) {
} }
template <class NodeTy> template <class NodeTy>
typename std::enable_if<std::is_base_of<UniquableMDNode, NodeTy>::value, typename std::enable_if<std::is_base_of<MDNode, NodeTy>::value, NodeTy *>::type
NodeTy *>::type
MDNode::replaceWithDistinct(std::unique_ptr<NodeTy, TempMDNodeDeleter> Node) { MDNode::replaceWithDistinct(std::unique_ptr<NodeTy, TempMDNodeDeleter> Node) {
Node->makeDistinct(); Node->makeDistinct();
return Node.release(); return Node.release();
} }
/// \brief Uniquable metadata node.
///
/// A uniquable metadata node. This contains the basic functionality
/// for implementing sub-types of \a MDNode that can be uniqued like
/// constants.
///
/// There is limited support for RAUW at construction time. At construction
/// time, if any operand is a temporary node (or an unresolved uniqued node,
/// which indicates a transitive temporary operand), the node itself will be
/// unresolved. As soon as all operands become resolved, it will drop RAUW
/// support permanently.
///
/// If an unresolved node is part of a cycle, \a resolveCycles() needs
/// to be called on some member of the cycle once all temporary nodes have been
/// replaced.
class UniquableMDNode : public MDNode {
friend class ReplaceableMetadataImpl;
friend class MDNode;
friend class LLVMContextImpl;
protected:
/// \brief Create a new node.
///
/// If \c AllowRAUW, then if any operands are unresolved support RAUW. RAUW
/// will be dropped once all operands have been resolved (or if \a
/// resolveCycles() is called).
UniquableMDNode(LLVMContext &C, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Vals);
~UniquableMDNode() {}
void storeDistinctInContext();
template <class T, class StoreT>
static T *storeImpl(T *N, StorageType Storage, StoreT &Store);
public:
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTupleKind ||
MD->getMetadataID() == MDLocationKind;
}
/// \brief Resolve cycles.
///
/// Once all forward declarations have been resolved, force cycles to be
/// resolved.
///
/// \pre No operands (or operands' operands, etc.) have \a isTemporary().
void resolveCycles();
private:
void handleChangedOperand(void *Ref, Metadata *New);
void resolve();
void resolveAfterOperandChange(Metadata *Old, Metadata *New);
void decrementUnresolvedOperandCount();
unsigned countUnresolvedOperands() const;
/// \brief Mutate this to be "uniqued".
///
/// Mutate this so that \a isUniqued().
/// \pre \a isTemporary().
/// \pre already added to uniquing set.
void makeUniqued();
/// \brief Mutate this to be "distinct".
///
/// Mutate this so that \a isDistinct().
/// \pre \a isTemporary().
void makeDistinct();
void deleteAsSubclass();
UniquableMDNode *uniquify();
void eraseFromStore();
};
/// \brief Tuple of metadata. /// \brief Tuple of metadata.
/// ///
/// This is the simple \a MDNode arbitrary tuple. Nodes are uniqued by /// This is the simple \a MDNode arbitrary tuple. Nodes are uniqued by
/// default based on their operands. /// default based on their operands.
class MDTuple : public UniquableMDNode { class MDTuple : public MDNode {
friend class LLVMContextImpl; friend class LLVMContextImpl;
friend class UniquableMDNode; friend class MDNode;
MDTuple(LLVMContext &C, StorageType Storage, unsigned Hash, MDTuple(LLVMContext &C, StorageType Storage, unsigned Hash,
ArrayRef<Metadata *> Vals) ArrayRef<Metadata *> Vals)
: UniquableMDNode(C, MDTupleKind, Storage, Vals) { : MDNode(C, MDTupleKind, Storage, Vals) {
setHash(Hash); setHash(Hash);
} }
~MDTuple() { dropAllReferences(); } ~MDTuple() { dropAllReferences(); }
@ -979,9 +953,9 @@ void TempMDNodeDeleter::operator()(MDNode *Node) const {
/// \brief Debug location. /// \brief Debug location.
/// ///
/// A debug location in source code, used for debug info and otherwise. /// A debug location in source code, used for debug info and otherwise.
class MDLocation : public UniquableMDNode { class MDLocation : public MDNode {
friend class LLVMContextImpl; friend class LLVMContextImpl;
friend class UniquableMDNode; friend class MDNode;
MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned Column, ArrayRef<Metadata *> MDs); unsigned Column, ArrayRef<Metadata *> MDs);

View File

@ -148,8 +148,8 @@ bool LLParser::ValidateEndOfModule() {
// Resolve metadata cycles. // Resolve metadata cycles.
for (auto &N : NumberedMetadata) for (auto &N : NumberedMetadata)
if (auto *U = cast_or_null<UniquableMDNode>(N)) if (N && !N->isResolved())
U->resolveCycles(); N->resolveCycles();
// Look for intrinsic functions and CallInst that need to be upgraded // Look for intrinsic functions and CallInst that need to be upgraded
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )

View File

@ -572,7 +572,7 @@ void BitcodeReaderMDValueList::tryToResolveCycles() {
// Resolve any cycles. // Resolve any cycles.
for (auto &MD : MDValuePtrs) { for (auto &MD : MDValuePtrs) {
auto *N = dyn_cast_or_null<UniquableMDNode>(MD); auto *N = dyn_cast_or_null<MDNode>(MD);
if (!N) if (!N)
continue; continue;

View File

@ -1311,16 +1311,15 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
const Module *Context) { const Module *Context) {
assert(!Node->isTemporary() && "Unexpected forward declaration"); assert(!Node->isTemporary() && "Unexpected forward declaration");
auto *Uniquable = cast<UniquableMDNode>(Node); if (Node->isDistinct())
if (Uniquable->isDistinct())
Out << "distinct "; Out << "distinct ";
switch (Uniquable->getMetadataID()) { switch (Node->getMetadataID()) {
default: default:
llvm_unreachable("Expected uniquable MDNode"); llvm_unreachable("Expected uniquable MDNode");
#define HANDLE_UNIQUABLE_LEAF(CLASS) \ #define HANDLE_MDNODE_LEAF(CLASS) \
case Metadata::CLASS##Kind: \ case Metadata::CLASS##Kind: \
write##CLASS(Out, cast<CLASS>(Uniquable), TypePrinter, Machine, Context); \ write##CLASS(Out, cast<CLASS>(Node), TypePrinter, Machine, Context); \
break; break;
#include "llvm/IR/Metadata.def" #include "llvm/IR/Metadata.def"
} }

View File

@ -105,8 +105,8 @@ void DIBuilder::finalize() {
// Now that all temp nodes have been replaced or deleted, resolve remaining // Now that all temp nodes have been replaced or deleted, resolve remaining
// cycles. // cycles.
for (const auto &N : UnresolvedNodes) for (const auto &N : UnresolvedNodes)
if (N) if (N && !N->isResolved())
cast<UniquableMDNode>(N)->resolveCycles(); N->resolveCycles();
UnresolvedNodes.clear(); UnresolvedNodes.clear();
// Can't handle unresolved nodes anymore. // Can't handle unresolved nodes anymore.

View File

@ -90,7 +90,7 @@ LLVMContextImpl::~LLVMContextImpl() {
Pair.second->dropUse(); Pair.second->dropUse();
// Destroy MDNodes. // Destroy MDNodes.
for (UniquableMDNode *I : DistinctMDNodes) for (MDNode *I : DistinctMDNodes)
I->deleteAsSubclass(); I->deleteAsSubclass();
for (MDTuple *I : MDTuples) for (MDTuple *I : MDTuples)
delete I; delete I;

View File

@ -320,7 +320,7 @@ public:
// aren't in the MDNodeSet, but they're still shared between objects, so no // 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 // one object can destroy them. This set allows us to at least destroy them
// on Context destruction. // on Context destruction.
SmallPtrSet<UniquableMDNode *, 1> DistinctMDNodes; SmallPtrSet<MDNode *, 1> DistinctMDNodes;
DenseMap<Type*, ConstantAggregateZero*> CAZConstants; DenseMap<Type*, ConstantAggregateZero*> CAZConstants;

View File

@ -228,8 +228,8 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
if (Owner.is<MetadataAsValue *>()) if (Owner.is<MetadataAsValue *>())
continue; continue;
// Resolve UniquableMDNodes that point at this. // Resolve MDNodes that point at this.
auto *OwnerMD = dyn_cast<UniquableMDNode>(Owner.get<Metadata *>()); auto *OwnerMD = dyn_cast<MDNode>(Owner.get<Metadata *>());
if (!OwnerMD) if (!OwnerMD)
continue; continue;
if (OwnerMD->isResolved()) if (OwnerMD->isResolved())
@ -406,17 +406,7 @@ MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
if (isTemporary()) if (isTemporary())
this->Context.makeReplaceable( this->Context.makeReplaceable(
make_unique<ReplaceableMetadataImpl>(Context)); make_unique<ReplaceableMetadataImpl>(Context));
}
static bool isOperandUnresolved(Metadata *Op) {
if (auto *N = dyn_cast_or_null<MDNode>(Op))
return !N->isResolved();
return false;
}
UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID,
StorageType Storage, ArrayRef<Metadata *> Vals)
: MDNode(C, ID, Storage, Vals) {
if (!isUniqued()) if (!isUniqued())
return; return;
@ -425,18 +415,24 @@ UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID,
if (!NumUnresolved) if (!NumUnresolved)
return; return;
this->Context.makeReplaceable(make_unique<ReplaceableMetadataImpl>(C)); this->Context.makeReplaceable(make_unique<ReplaceableMetadataImpl>(Context));
SubclassData32 = NumUnresolved; SubclassData32 = NumUnresolved;
} }
unsigned UniquableMDNode::countUnresolvedOperands() const { static bool isOperandUnresolved(Metadata *Op) {
if (auto *N = dyn_cast_or_null<MDNode>(Op))
return !N->isResolved();
return false;
}
unsigned MDNode::countUnresolvedOperands() const {
unsigned NumUnresolved = 0; unsigned NumUnresolved = 0;
for (const auto &Op : operands()) for (const auto &Op : operands())
NumUnresolved += unsigned(isOperandUnresolved(Op)); NumUnresolved += unsigned(isOperandUnresolved(Op));
return NumUnresolved; return NumUnresolved;
} }
void UniquableMDNode::makeUniqued() { void MDNode::makeUniqued() {
assert(isTemporary() && "Expected this to be temporary"); assert(isTemporary() && "Expected this to be temporary");
assert(!isResolved() && "Expected this to be unresolved"); assert(!isResolved() && "Expected this to be unresolved");
@ -450,7 +446,7 @@ void UniquableMDNode::makeUniqued() {
assert(isUniqued() && "Expected this to be uniqued"); assert(isUniqued() && "Expected this to be uniqued");
} }
void UniquableMDNode::makeDistinct() { void MDNode::makeDistinct() {
assert(isTemporary() && "Expected this to be temporary"); assert(isTemporary() && "Expected this to be temporary");
assert(!isResolved() && "Expected this to be unresolved"); assert(!isResolved() && "Expected this to be unresolved");
@ -463,7 +459,7 @@ void UniquableMDNode::makeDistinct() {
assert(isResolved() && "Expected this to be resolved"); assert(isResolved() && "Expected this to be resolved");
} }
void UniquableMDNode::resolve() { void MDNode::resolve() {
assert(isUniqued() && "Expected this to be uniqued"); assert(isUniqued() && "Expected this to be uniqued");
assert(!isResolved() && "Expected this to be unresolved"); assert(!isResolved() && "Expected this to be unresolved");
@ -476,7 +472,7 @@ void UniquableMDNode::resolve() {
Uses->resolveAllUses(); Uses->resolveAllUses();
} }
void UniquableMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) { void MDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
assert(SubclassData32 != 0 && "Expected unresolved operands"); assert(SubclassData32 != 0 && "Expected unresolved operands");
// Check if an operand was resolved. // Check if an operand was resolved.
@ -488,13 +484,13 @@ void UniquableMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
decrementUnresolvedOperandCount(); decrementUnresolvedOperandCount();
} }
void UniquableMDNode::decrementUnresolvedOperandCount() { void MDNode::decrementUnresolvedOperandCount() {
if (!--SubclassData32) if (!--SubclassData32)
// Last unresolved operand has just been resolved. // Last unresolved operand has just been resolved.
resolve(); resolve();
} }
void UniquableMDNode::resolveCycles() { void MDNode::resolveCycles() {
if (isResolved()) if (isResolved())
return; return;
@ -503,7 +499,7 @@ void UniquableMDNode::resolveCycles() {
// Resolve all operands. // Resolve all operands.
for (const auto &Op : operands()) { for (const auto &Op : operands()) {
auto *N = dyn_cast_or_null<UniquableMDNode>(Op); auto *N = dyn_cast_or_null<MDNode>(Op);
if (!N) if (!N)
continue; continue;
@ -521,14 +517,13 @@ void MDTuple::recalculateHash() {
void MDNode::dropAllReferences() { void MDNode::dropAllReferences() {
for (unsigned I = 0, E = NumOperands; I != E; ++I) for (unsigned I = 0, E = NumOperands; I != E; ++I)
setOperand(I, nullptr); setOperand(I, nullptr);
if (auto *N = dyn_cast<UniquableMDNode>(this)) if (!isResolved()) {
if (!N->isResolved()) { Context.getReplaceableUses()->resolveAllUses(/* ResolveUsers */ false);
N->Context.getReplaceableUses()->resolveAllUses(/* ResolveUsers */ false); (void)Context.takeReplaceableUses();
(void)N->Context.takeReplaceableUses(); }
}
} }
void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) { void MDNode::handleChangedOperand(void *Ref, Metadata *New) {
unsigned Op = static_cast<MDOperand *>(Ref) - op_begin(); unsigned Op = static_cast<MDOperand *>(Ref) - op_begin();
assert(Op < getNumOperands() && "Expected valid operand"); assert(Op < getNumOperands() && "Expected valid operand");
@ -577,11 +572,11 @@ void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {
storeDistinctInContext(); storeDistinctInContext();
} }
void UniquableMDNode::deleteAsSubclass() { void MDNode::deleteAsSubclass() {
switch (getMetadataID()) { switch (getMetadataID()) {
default: default:
llvm_unreachable("Invalid subclass of UniquableMDNode"); llvm_unreachable("Invalid subclass of MDNode");
#define HANDLE_UNIQUABLE_LEAF(CLASS) \ #define HANDLE_MDNODE_LEAF(CLASS) \
case CLASS##Kind: \ case CLASS##Kind: \
delete cast<CLASS>(this); \ delete cast<CLASS>(this); \
break; break;
@ -605,7 +600,7 @@ static T *uniquifyImpl(T *N, DenseSet<T *, InfoT> &Store) {
return N; return N;
} }
UniquableMDNode *UniquableMDNode::uniquify() { MDNode *MDNode::uniquify() {
// Recalculate hash, if necessary. // Recalculate hash, if necessary.
switch (getMetadataID()) { switch (getMetadataID()) {
default: default:
@ -618,19 +613,19 @@ UniquableMDNode *UniquableMDNode::uniquify() {
// Try to insert into uniquing store. // Try to insert into uniquing store.
switch (getMetadataID()) { switch (getMetadataID()) {
default: default:
llvm_unreachable("Invalid subclass of UniquableMDNode"); llvm_unreachable("Invalid subclass of MDNode");
#define HANDLE_UNIQUABLE_LEAF(CLASS) \ #define HANDLE_MDNODE_LEAF(CLASS) \
case CLASS##Kind: \ case CLASS##Kind: \
return uniquifyImpl(cast<CLASS>(this), getContext().pImpl->CLASS##s); return uniquifyImpl(cast<CLASS>(this), getContext().pImpl->CLASS##s);
#include "llvm/IR/Metadata.def" #include "llvm/IR/Metadata.def"
} }
} }
void UniquableMDNode::eraseFromStore() { void MDNode::eraseFromStore() {
switch (getMetadataID()) { switch (getMetadataID()) {
default: default:
llvm_unreachable("Invalid subclass of UniquableMDNode"); llvm_unreachable("Invalid subclass of MDNode");
#define HANDLE_UNIQUABLE_LEAF(CLASS) \ #define HANDLE_MDNODE_LEAF(CLASS) \
case CLASS##Kind: \ case CLASS##Kind: \
getContext().pImpl->CLASS##s.erase(cast<CLASS>(this)); \ getContext().pImpl->CLASS##s.erase(cast<CLASS>(this)); \
break; break;
@ -639,7 +634,7 @@ void UniquableMDNode::eraseFromStore() {
} }
template <class T, class StoreT> template <class T, class StoreT>
T *UniquableMDNode::storeImpl(T *N, StorageType Storage, StoreT &Store) { T *MDNode::storeImpl(T *N, StorageType Storage, StoreT &Store) {
switch (Storage) { switch (Storage) {
case Uniqued: case Uniqued:
Store.insert(N); Store.insert(N);
@ -673,7 +668,7 @@ MDTuple *MDTuple::getImpl(LLVMContext &Context, ArrayRef<Metadata *> MDs,
MDLocation::MDLocation(LLVMContext &C, StorageType Storage, unsigned Line, MDLocation::MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned Column, ArrayRef<Metadata *> MDs) unsigned Column, ArrayRef<Metadata *> MDs)
: UniquableMDNode(C, MDLocationKind, Storage, MDs) { : MDNode(C, MDLocationKind, Storage, MDs) {
assert((MDs.size() == 1 || MDs.size() == 2) && assert((MDs.size() == 1 || MDs.size() == 2) &&
"Expected a scope and optional inlined-at"); "Expected a scope and optional inlined-at");
@ -727,10 +722,10 @@ MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line,
void MDNode::deleteTemporary(MDNode *N) { void MDNode::deleteTemporary(MDNode *N) {
assert(N->isTemporary() && "Expected temporary node"); assert(N->isTemporary() && "Expected temporary node");
cast<UniquableMDNode>(N)->deleteAsSubclass(); N->deleteAsSubclass();
} }
void UniquableMDNode::storeDistinctInContext() { void MDNode::storeDistinctInContext() {
assert(isResolved() && "Expected resolved nodes"); assert(isResolved() && "Expected resolved nodes");
Storage = Distinct; Storage = Distinct;
if (auto *T = dyn_cast<MDTuple>(this)) if (auto *T = dyn_cast<MDTuple>(this))
@ -747,7 +742,7 @@ void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
return; return;
} }
cast<UniquableMDNode>(this)->handleChangedOperand(mutable_begin() + I, New); handleChangedOperand(mutable_begin() + I, New);
} }
void MDNode::setOperand(unsigned I, Metadata *New) { void MDNode::setOperand(unsigned I, Metadata *New) {

View File

@ -192,11 +192,11 @@ static TempMDLocation cloneMDLocation(const MDLocation *Node) {
Node->getInlinedAt()); Node->getInlinedAt());
} }
static TempUniquableMDNode cloneMDNode(const UniquableMDNode *Node) { static TempMDNode cloneMDNode(const MDNode *Node) {
switch (Node->getMetadataID()) { switch (Node->getMetadataID()) {
default: default:
llvm_unreachable("Invalid UniquableMDNode subclass"); llvm_unreachable("Invalid MDNode subclass");
#define HANDLE_UNIQUABLE_LEAF(CLASS) \ #define HANDLE_MDNODE_LEAF(CLASS) \
case Metadata::CLASS##Kind: \ case Metadata::CLASS##Kind: \
return clone##CLASS(cast<CLASS>(Node)); return clone##CLASS(cast<CLASS>(Node));
#include "llvm/IR/Metadata.def" #include "llvm/IR/Metadata.def"
@ -209,9 +209,8 @@ static TempUniquableMDNode cloneMDNode(const UniquableMDNode *Node) {
/// Assumes that \c NewNode is already a clone of \c OldNode. /// Assumes that \c NewNode is already a clone of \c OldNode.
/// ///
/// \pre \c NewNode is a clone of \c OldNode. /// \pre \c NewNode is a clone of \c OldNode.
static bool remap(const UniquableMDNode *OldNode, UniquableMDNode *NewNode, static bool remap(const MDNode *OldNode, MDNode *NewNode, ValueToValueMapTy &VM,
ValueToValueMapTy &VM, RemapFlags Flags, RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) { ValueMaterializer *Materializer) {
assert(OldNode->getNumOperands() == NewNode->getNumOperands() && assert(OldNode->getNumOperands() == NewNode->getNumOperands() &&
"Expected nodes to match"); "Expected nodes to match");
@ -240,13 +239,13 @@ static bool remap(const UniquableMDNode *OldNode, UniquableMDNode *NewNode,
/// \brief Map a distinct MDNode. /// \brief Map a distinct MDNode.
/// ///
/// Distinct nodes are not uniqued, so they must always recreated. /// Distinct nodes are not uniqued, so they must always recreated.
static Metadata *mapDistinctNode(const UniquableMDNode *Node, static Metadata *mapDistinctNode(const MDNode *Node, ValueToValueMapTy &VM,
ValueToValueMapTy &VM, RemapFlags Flags, RemapFlags Flags,
ValueMapTypeRemapper *TypeMapper, ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) { ValueMaterializer *Materializer) {
assert(Node->isDistinct() && "Expected distinct node"); assert(Node->isDistinct() && "Expected distinct node");
UniquableMDNode *NewMD = MDNode::replaceWithDistinct(cloneMDNode(Node)); MDNode *NewMD = MDNode::replaceWithDistinct(cloneMDNode(Node));
remap(Node, NewMD, VM, Flags, TypeMapper, Materializer); remap(Node, NewMD, VM, Flags, TypeMapper, Materializer);
return NewMD; return NewMD;
} }
@ -254,8 +253,8 @@ static Metadata *mapDistinctNode(const UniquableMDNode *Node,
/// \brief Map a uniqued MDNode. /// \brief Map a uniqued MDNode.
/// ///
/// Uniqued nodes may not need to be recreated (they may map to themselves). /// Uniqued nodes may not need to be recreated (they may map to themselves).
static Metadata *mapUniquedNode(const UniquableMDNode *Node, static Metadata *mapUniquedNode(const MDNode *Node, ValueToValueMapTy &VM,
ValueToValueMapTy &VM, RemapFlags Flags, RemapFlags Flags,
ValueMapTypeRemapper *TypeMapper, ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer) { ValueMaterializer *Materializer) {
assert(Node->isUniqued() && "Expected uniqued node"); assert(Node->isUniqued() && "Expected uniqued node");
@ -304,7 +303,7 @@ static Metadata *MapMetadataImpl(const Metadata *MD, ValueToValueMapTy &VM,
return nullptr; return nullptr;
} }
const UniquableMDNode *Node = cast<UniquableMDNode>(MD); const MDNode *Node = cast<MDNode>(MD);
assert(Node->isResolved() && "Unexpected unresolved node"); assert(Node->isResolved() && "Unexpected unresolved node");
// If this is a module-level metadata and we know that nothing at the // If this is a module-level metadata and we know that nothing at the
@ -323,8 +322,9 @@ Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
ValueMaterializer *Materializer) { ValueMaterializer *Materializer) {
Metadata *NewMD = MapMetadataImpl(MD, VM, Flags, TypeMapper, Materializer); Metadata *NewMD = MapMetadataImpl(MD, VM, Flags, TypeMapper, Materializer);
if (NewMD && NewMD != MD) if (NewMD && NewMD != MD)
if (auto *N = dyn_cast<UniquableMDNode>(NewMD)) if (auto *N = dyn_cast<MDNode>(NewMD))
N->resolveCycles(); if (!N->isResolved())
N->resolveCycles();
return NewMD; return NewMD;
} }