mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-02 20:38:34 +00:00
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:
parent
fce53dd939
commit
b0617860b5
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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; )
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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,7 +322,8 @@ 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))
|
||||||
|
if (!N->isResolved())
|
||||||
N->resolveCycles();
|
N->resolveCycles();
|
||||||
return NewMD;
|
return NewMD;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user