mirror of
https://github.com/RPCSX/llvm.git
synced 2025-05-13 19:06:05 +00:00
IR: Split GenericMDNode into MDTuple and UniquableMDNode
Split `GenericMDNode` into two classes (with more descriptive names). - `UniquableMDNode` will be a common subclass for `MDNode`s that are sometimes uniqued like constants, and sometimes 'distinct'. This class gets the (short-lived) RAUW support and related API. - `MDTuple` is the basic tuple that has always been returned by `MDNode::get()`. This is as opposed to more specific nodes to be added soon, which have additional fields, custom assembly syntax, and extra semantics. This class gets the hash-related logic, since other sublcasses of `UniquableMDNode` may need to hash based on other fields. To keep this diff from getting too big, I've added casts to `MDTuple` that won't really scale as new subclasses of `UniquableMDNode` are added, but I'll clean those up incrementally. (No functionality change intended.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225682 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2d88dc293b
commit
ae9e15f914
@ -37,7 +37,8 @@ HANDLE_METADATA_LEAF(ConstantAsMetadata)
|
|||||||
HANDLE_METADATA_LEAF(LocalAsMetadata)
|
HANDLE_METADATA_LEAF(LocalAsMetadata)
|
||||||
HANDLE_METADATA_BRANCH(MDNode)
|
HANDLE_METADATA_BRANCH(MDNode)
|
||||||
HANDLE_METADATA_LEAF(MDNodeFwdDecl)
|
HANDLE_METADATA_LEAF(MDNodeFwdDecl)
|
||||||
HANDLE_METADATA_LEAF(GenericMDNode)
|
HANDLE_METADATA_BRANCH(UniquableMDNode)
|
||||||
|
HANDLE_METADATA_LEAF(MDTuple)
|
||||||
|
|
||||||
#undef HANDLE_METADATA
|
#undef HANDLE_METADATA
|
||||||
#undef HANDLE_METADATA_LEAF
|
#undef HANDLE_METADATA_LEAF
|
||||||
|
@ -56,7 +56,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum MetadataKind {
|
enum MetadataKind {
|
||||||
GenericMDNodeKind,
|
MDTupleKind,
|
||||||
MDNodeFwdDeclKind,
|
MDNodeFwdDeclKind,
|
||||||
ConstantAsMetadataKind,
|
ConstantAsMetadataKind,
|
||||||
LocalAsMetadataKind,
|
LocalAsMetadataKind,
|
||||||
@ -158,7 +158,7 @@ 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 GenericMDNode::resolve() on any users whose last
|
/// ResolveUsers, call \a UniquableMDNode::resolve() on any users whose last
|
||||||
/// operand is resolved.
|
/// operand is resolved.
|
||||||
void resolveAllUses(bool ResolveUsers = true);
|
void resolveAllUses(bool ResolveUsers = true);
|
||||||
|
|
||||||
@ -682,7 +682,7 @@ public:
|
|||||||
|
|
||||||
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
static bool classof(const Metadata *MD) {
|
static bool classof(const Metadata *MD) {
|
||||||
return MD->getMetadataID() == GenericMDNodeKind ||
|
return MD->getMetadataID() == MDTupleKind ||
|
||||||
MD->getMetadataID() == MDNodeFwdDeclKind;
|
MD->getMetadataID() == MDNodeFwdDeclKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,46 +698,46 @@ public:
|
|||||||
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
|
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Generic metadata node.
|
/// \brief Uniquable metadata node.
|
||||||
///
|
///
|
||||||
/// Generic metadata nodes, with opt-out support for uniquing.
|
/// A uniquable metadata node. This contains the basic functionality
|
||||||
|
/// for implementing sub-types of \a MDNode that can be uniqued like
|
||||||
|
/// constants.
|
||||||
///
|
///
|
||||||
/// Although nodes are uniqued by default, \a GenericMDNode has no support for
|
/// There is limited support for RAUW at construction time. At
|
||||||
/// RAUW. If an operand change (due to RAUW or otherwise) causes a uniquing
|
/// construction time, if any operands are an instance of \a
|
||||||
/// collision, the uniquing bit is dropped.
|
/// MDNodeFwdDecl (or another unresolved \a UniquableMDNode, which
|
||||||
class GenericMDNode : public MDNode {
|
/// indicates an \a MDNodeFwdDecl in its path), the node itself will be
|
||||||
friend class Metadata;
|
/// 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 when each \a MDNodeFwdDecl
|
||||||
|
/// has been removed.
|
||||||
|
class UniquableMDNode : public MDNode {
|
||||||
|
friend class ReplaceableMetadataImpl;
|
||||||
friend class MDNode;
|
friend class MDNode;
|
||||||
friend class LLVMContextImpl;
|
friend class LLVMContextImpl;
|
||||||
friend class ReplaceableMetadataImpl;
|
|
||||||
|
|
||||||
/// \brief Support RAUW as long as one of its arguments is replaceable.
|
/// \brief Support RAUW as long as one of its arguments is replaceable.
|
||||||
///
|
///
|
||||||
/// If an operand is an \a MDNodeFwdDecl (or a replaceable \a GenericMDNode),
|
|
||||||
/// support RAUW to support uniquing as forward declarations are resolved.
|
|
||||||
/// As soon as operands have been resolved, drop support.
|
|
||||||
///
|
|
||||||
/// FIXME: Save memory by storing this in a pointer union with the
|
/// FIXME: Save memory by storing this in a pointer union with the
|
||||||
/// LLVMContext, and adding an LLVMContext reference to RMI.
|
/// LLVMContext, and adding an LLVMContext reference to RMI.
|
||||||
std::unique_ptr<ReplaceableMetadataImpl> ReplaceableUses;
|
std::unique_ptr<ReplaceableMetadataImpl> ReplaceableUses;
|
||||||
|
|
||||||
|
protected:
|
||||||
/// \brief Create a new node.
|
/// \brief Create a new node.
|
||||||
///
|
///
|
||||||
/// If \c AllowRAUW, then if any operands are unresolved support RAUW. RAUW
|
/// If \c AllowRAUW, then if any operands are unresolved support RAUW. RAUW
|
||||||
/// will be dropped once all operands have been resolved (or if \a
|
/// will be dropped once all operands have been resolved (or if \a
|
||||||
/// resolveCycles() is called).
|
/// resolveCycles() is called).
|
||||||
GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals, bool AllowRAUW);
|
UniquableMDNode(LLVMContext &C, unsigned ID, ArrayRef<Metadata *> Vals,
|
||||||
~GenericMDNode();
|
bool AllowRAUW);
|
||||||
|
~UniquableMDNode();
|
||||||
void setHash(unsigned Hash) { MDNodeSubclassData = Hash; }
|
|
||||||
void recalculateHash();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \brief Get the hash, if any.
|
|
||||||
unsigned getHash() const { return MDNodeSubclassData; }
|
|
||||||
|
|
||||||
static bool classof(const Metadata *MD) {
|
static bool classof(const Metadata *MD) {
|
||||||
return MD->getMetadataID() == GenericMDNodeKind;
|
return MD->getMetadataID() == MDTupleKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Check whether any operands are forward declarations.
|
/// \brief Check whether any operands are forward declarations.
|
||||||
@ -766,11 +766,36 @@ private:
|
|||||||
void decrementUnresolvedOperandCount();
|
void decrementUnresolvedOperandCount();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief Tuple of metadata.
|
||||||
|
///
|
||||||
|
/// This is the simple \a MDNode arbitrary tuple. Nodes are uniqued by
|
||||||
|
/// default based on their operands.
|
||||||
|
class MDTuple : public UniquableMDNode {
|
||||||
|
friend class LLVMContextImpl;
|
||||||
|
friend class UniquableMDNode;
|
||||||
|
friend class MDNode;
|
||||||
|
|
||||||
|
MDTuple(LLVMContext &C, ArrayRef<Metadata *> Vals, bool AllowRAUW)
|
||||||
|
: UniquableMDNode(C, MDTupleKind, Vals, AllowRAUW) {}
|
||||||
|
~MDTuple();
|
||||||
|
|
||||||
|
void setHash(unsigned Hash) { MDNodeSubclassData = Hash; }
|
||||||
|
void recalculateHash();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// \brief Get the hash, if any.
|
||||||
|
unsigned getHash() const { return MDNodeSubclassData; }
|
||||||
|
|
||||||
|
static bool classof(const Metadata *MD) {
|
||||||
|
return MD->getMetadataID() == MDTupleKind;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief Forward declaration of metadata.
|
/// \brief Forward declaration of metadata.
|
||||||
///
|
///
|
||||||
/// Forward declaration of metadata, in the form of a metadata node. Unlike \a
|
/// Forward declaration of metadata, in the form of a basic tuple. Unlike \a
|
||||||
/// GenericMDNode, this class has support for RAUW and is suitable for forward
|
/// MDTuple, this class has full support for RAUW, is not owned, is not
|
||||||
/// references.
|
/// uniqued, and is suitable for forward references.
|
||||||
class MDNodeFwdDecl : public MDNode, ReplaceableMetadataImpl {
|
class MDNodeFwdDecl : public MDNode, ReplaceableMetadataImpl {
|
||||||
friend class Metadata;
|
friend class Metadata;
|
||||||
friend class MDNode;
|
friend class MDNode;
|
||||||
|
@ -169,8 +169,8 @@ bool LLParser::ValidateEndOfModule() {
|
|||||||
|
|
||||||
// Resolve metadata cycles.
|
// Resolve metadata cycles.
|
||||||
for (auto &N : NumberedMetadata)
|
for (auto &N : NumberedMetadata)
|
||||||
if (auto *G = cast_or_null<GenericMDNode>(N))
|
if (auto *U = cast_or_null<UniquableMDNode>(N))
|
||||||
G->resolveCycles();
|
U->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; )
|
||||||
|
@ -558,8 +558,8 @@ void BitcodeReaderMDValueList::tryToResolveCycles() {
|
|||||||
// Resolve any cycles.
|
// Resolve any cycles.
|
||||||
for (auto &MD : MDValuePtrs) {
|
for (auto &MD : MDValuePtrs) {
|
||||||
assert(!(MD && isa<MDNodeFwdDecl>(MD)) && "Unexpected forward reference");
|
assert(!(MD && isa<MDNodeFwdDecl>(MD)) && "Unexpected forward reference");
|
||||||
if (auto *G = dyn_cast_or_null<GenericMDNode>(MD))
|
if (auto *N = dyn_cast_or_null<UniquableMDNode>(MD))
|
||||||
G->resolveCycles();
|
N->resolveCycles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,8 @@ DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes)
|
|||||||
AllowUnresolvedNodes(AllowUnresolvedNodes) {}
|
AllowUnresolvedNodes(AllowUnresolvedNodes) {}
|
||||||
|
|
||||||
static bool isUnresolved(MDNode *N) {
|
static bool isUnresolved(MDNode *N) {
|
||||||
return N && (isa<MDNodeFwdDecl>(N) || !cast<GenericMDNode>(N)->isResolved());
|
return N &&
|
||||||
|
(isa<MDNodeFwdDecl>(N) || !cast<UniquableMDNode>(N)->isResolved());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DIBuilder::trackIfUnresolved(MDNode *N) {
|
void DIBuilder::trackIfUnresolved(MDNode *N) {
|
||||||
@ -110,7 +111,7 @@ void DIBuilder::finalize() {
|
|||||||
// cycles.
|
// cycles.
|
||||||
for (const auto &N : UnresolvedNodes)
|
for (const auto &N : UnresolvedNodes)
|
||||||
if (N)
|
if (N)
|
||||||
cast<GenericMDNode>(N)->resolveCycles();
|
cast<UniquableMDNode>(N)->resolveCycles();
|
||||||
UnresolvedNodes.clear();
|
UnresolvedNodes.clear();
|
||||||
|
|
||||||
// Can't handle unresolved nodes anymore.
|
// Can't handle unresolved nodes anymore.
|
||||||
|
@ -135,17 +135,17 @@ LLVMContextImpl::~LLVMContextImpl() {
|
|||||||
for (auto &Pair : ValuesAsMetadata)
|
for (auto &Pair : ValuesAsMetadata)
|
||||||
delete Pair.second;
|
delete Pair.second;
|
||||||
|
|
||||||
// Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet
|
// Destroy MDNodes. ~MDNode can move and remove nodes between the MDTuples
|
||||||
// and the NonUniquedMDNodes sets, so copy the values out first.
|
// and the DistinctMDNodes sets, so copy the values out first.
|
||||||
SmallVector<GenericMDNode *, 8> MDNodes;
|
SmallVector<UniquableMDNode *, 8> Uniquables;
|
||||||
MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size());
|
Uniquables.reserve(MDTuples.size() + DistinctMDNodes.size());
|
||||||
MDNodes.append(MDNodeSet.begin(), MDNodeSet.end());
|
Uniquables.append(MDTuples.begin(), MDTuples.end());
|
||||||
MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end());
|
Uniquables.append(DistinctMDNodes.begin(), DistinctMDNodes.end());
|
||||||
for (GenericMDNode *I : MDNodes)
|
for (UniquableMDNode *I : Uniquables)
|
||||||
I->dropAllReferences();
|
I->dropAllReferences();
|
||||||
for (GenericMDNode *I : MDNodes)
|
for (UniquableMDNode *I : Uniquables)
|
||||||
delete I;
|
delete cast<MDTuple>(I);
|
||||||
assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() &&
|
assert(MDTuples.empty() && DistinctMDNodes.empty() &&
|
||||||
"Destroying all MDNodes didn't empty the Context's sets.");
|
"Destroying all MDNodes didn't empty the Context's sets.");
|
||||||
|
|
||||||
// Destroy MDStrings.
|
// Destroy MDStrings.
|
||||||
|
@ -166,11 +166,11 @@ struct FunctionTypeKeyInfo {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief DenseMapInfo for GenericMDNode.
|
/// \brief DenseMapInfo for MDTuple.
|
||||||
///
|
///
|
||||||
/// Note that we don't need the is-function-local bit, since that's implicit in
|
/// Note that we don't need the is-function-local bit, since that's implicit in
|
||||||
/// the operands.
|
/// the operands.
|
||||||
struct GenericMDNodeInfo {
|
struct MDTupleInfo {
|
||||||
struct KeyTy {
|
struct KeyTy {
|
||||||
ArrayRef<Metadata *> RawOps;
|
ArrayRef<Metadata *> RawOps;
|
||||||
ArrayRef<MDOperand> Ops;
|
ArrayRef<MDOperand> Ops;
|
||||||
@ -179,10 +179,10 @@ struct GenericMDNodeInfo {
|
|||||||
KeyTy(ArrayRef<Metadata *> Ops)
|
KeyTy(ArrayRef<Metadata *> Ops)
|
||||||
: RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
|
: RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
|
||||||
|
|
||||||
KeyTy(GenericMDNode *N)
|
KeyTy(MDTuple *N)
|
||||||
: Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}
|
: Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}
|
||||||
|
|
||||||
bool operator==(const GenericMDNode *RHS) const {
|
bool operator==(const MDTuple *RHS) const {
|
||||||
if (RHS == getEmptyKey() || RHS == getTombstoneKey())
|
if (RHS == getEmptyKey() || RHS == getTombstoneKey())
|
||||||
return false;
|
return false;
|
||||||
if (Hash != RHS->getHash())
|
if (Hash != RHS->getHash())
|
||||||
@ -191,26 +191,26 @@ struct GenericMDNodeInfo {
|
|||||||
return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS);
|
return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
static bool compareOps(ArrayRef<T> Ops, const GenericMDNode *RHS) {
|
static bool compareOps(ArrayRef<T> Ops, const MDTuple *RHS) {
|
||||||
if (Ops.size() != RHS->getNumOperands())
|
if (Ops.size() != RHS->getNumOperands())
|
||||||
return false;
|
return false;
|
||||||
return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());
|
return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static inline GenericMDNode *getEmptyKey() {
|
static inline MDTuple *getEmptyKey() {
|
||||||
return DenseMapInfo<GenericMDNode *>::getEmptyKey();
|
return DenseMapInfo<MDTuple *>::getEmptyKey();
|
||||||
}
|
}
|
||||||
static inline GenericMDNode *getTombstoneKey() {
|
static inline MDTuple *getTombstoneKey() {
|
||||||
return DenseMapInfo<GenericMDNode *>::getTombstoneKey();
|
return DenseMapInfo<MDTuple *>::getTombstoneKey();
|
||||||
}
|
}
|
||||||
static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; }
|
static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; }
|
||||||
static unsigned getHashValue(const GenericMDNode *U) {
|
static unsigned getHashValue(const MDTuple *U) {
|
||||||
return U->getHash();
|
return U->getHash();
|
||||||
}
|
}
|
||||||
static bool isEqual(const KeyTy &LHS, const GenericMDNode *RHS) {
|
static bool isEqual(const KeyTy &LHS, const MDTuple *RHS) {
|
||||||
return LHS == RHS;
|
return LHS == RHS;
|
||||||
}
|
}
|
||||||
static bool isEqual(const GenericMDNode *LHS, const GenericMDNode *RHS) {
|
static bool isEqual(const MDTuple *LHS, const MDTuple *RHS) {
|
||||||
return LHS == RHS;
|
return LHS == RHS;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -245,13 +245,13 @@ public:
|
|||||||
DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
|
DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
|
||||||
DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
|
DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
|
||||||
|
|
||||||
DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet;
|
DenseSet<MDTuple *, MDTupleInfo> MDTuples;
|
||||||
|
|
||||||
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they
|
// 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
|
// 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<GenericMDNode *, 1> NonUniquedMDNodes;
|
SmallPtrSet<UniquableMDNode *, 1> DistinctMDNodes;
|
||||||
|
|
||||||
DenseMap<Type*, ConstantAggregateZero*> CAZConstants;
|
DenseMap<Type*, ConstantAggregateZero*> CAZConstants;
|
||||||
|
|
||||||
|
@ -222,8 +222,8 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
|
|||||||
if (Owner.is<MetadataAsValue *>())
|
if (Owner.is<MetadataAsValue *>())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Resolve GenericMDNodes that point at this.
|
// Resolve UniquableMDNodes that point at this.
|
||||||
auto *OwnerMD = dyn_cast<GenericMDNode>(Owner.get<Metadata *>());
|
auto *OwnerMD = dyn_cast<UniquableMDNode>(Owner.get<Metadata *>());
|
||||||
if (!OwnerMD)
|
if (!OwnerMD)
|
||||||
continue;
|
continue;
|
||||||
if (OwnerMD->isResolved())
|
if (OwnerMD->isResolved())
|
||||||
@ -400,7 +400,7 @@ MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs)
|
|||||||
bool MDNode::isResolved() const {
|
bool MDNode::isResolved() const {
|
||||||
if (isa<MDNodeFwdDecl>(this))
|
if (isa<MDNodeFwdDecl>(this))
|
||||||
return false;
|
return false;
|
||||||
return cast<GenericMDNode>(this)->isResolved();
|
return cast<UniquableMDNode>(this)->isResolved();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isOperandUnresolved(Metadata *Op) {
|
static bool isOperandUnresolved(Metadata *Op) {
|
||||||
@ -409,9 +409,9 @@ static bool isOperandUnresolved(Metadata *Op) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals,
|
UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID,
|
||||||
bool AllowRAUW)
|
ArrayRef<Metadata *> Vals, bool AllowRAUW)
|
||||||
: MDNode(C, GenericMDNodeKind, Vals) {
|
: MDNode(C, ID, Vals) {
|
||||||
if (!AllowRAUW)
|
if (!AllowRAUW)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -427,16 +427,14 @@ GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals,
|
|||||||
SubclassData32 = NumUnresolved;
|
SubclassData32 = NumUnresolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericMDNode::~GenericMDNode() {
|
UniquableMDNode::~UniquableMDNode() {
|
||||||
LLVMContextImpl *pImpl = getContext().pImpl;
|
|
||||||
if (isStoredDistinctInContext())
|
if (isStoredDistinctInContext())
|
||||||
pImpl->NonUniquedMDNodes.erase(this);
|
getContext().pImpl->DistinctMDNodes.erase(this);
|
||||||
else
|
|
||||||
pImpl->MDNodeSet.erase(this);
|
|
||||||
dropAllReferences();
|
dropAllReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericMDNode::resolve() {
|
void UniquableMDNode::resolve() {
|
||||||
assert(!isResolved() && "Expected this to be unresolved");
|
assert(!isResolved() && "Expected this to be unresolved");
|
||||||
|
|
||||||
// Move the map, so that this immediately looks resolved.
|
// Move the map, so that this immediately looks resolved.
|
||||||
@ -448,7 +446,7 @@ void GenericMDNode::resolve() {
|
|||||||
Uses->resolveAllUses();
|
Uses->resolveAllUses();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
|
void UniquableMDNode::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.
|
||||||
@ -458,13 +456,13 @@ void GenericMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
|
|||||||
decrementUnresolvedOperandCount();
|
decrementUnresolvedOperandCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericMDNode::decrementUnresolvedOperandCount() {
|
void UniquableMDNode::decrementUnresolvedOperandCount() {
|
||||||
if (!--SubclassData32)
|
if (!--SubclassData32)
|
||||||
// Last unresolved operand has just been resolved.
|
// Last unresolved operand has just been resolved.
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericMDNode::resolveCycles() {
|
void UniquableMDNode::resolveCycles() {
|
||||||
if (isResolved())
|
if (isResolved())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -477,13 +475,18 @@ void GenericMDNode::resolveCycles() {
|
|||||||
continue;
|
continue;
|
||||||
assert(!isa<MDNodeFwdDecl>(Op) &&
|
assert(!isa<MDNodeFwdDecl>(Op) &&
|
||||||
"Expected all forward declarations to be resolved");
|
"Expected all forward declarations to be resolved");
|
||||||
if (auto *N = dyn_cast<GenericMDNode>(Op))
|
if (auto *N = dyn_cast<UniquableMDNode>(Op))
|
||||||
if (!N->isResolved())
|
if (!N->isResolved())
|
||||||
N->resolveCycles();
|
N->resolveCycles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericMDNode::recalculateHash() {
|
MDTuple::~MDTuple() {
|
||||||
|
if (!isStoredDistinctInContext())
|
||||||
|
getContext().pImpl->MDTuples.erase(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDTuple::recalculateHash() {
|
||||||
setHash(hash_combine_range(op_begin(), op_end()));
|
setHash(hash_combine_range(op_begin(), op_end()));
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
{
|
{
|
||||||
@ -498,10 +501,10 @@ void GenericMDNode::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 *G = dyn_cast<GenericMDNode>(this))
|
if (auto *N = dyn_cast<UniquableMDNode>(this))
|
||||||
if (!G->isResolved()) {
|
if (!N->isResolved()) {
|
||||||
G->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);
|
N->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);
|
||||||
G->ReplaceableUses.reset();
|
N->ReplaceableUses.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +525,7 @@ namespace llvm {
|
|||||||
static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
|
static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
|
void UniquableMDNode::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");
|
||||||
|
|
||||||
@ -534,8 +537,8 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &Store = getContext().pImpl->MDNodeSet;
|
auto &Store = getContext().pImpl->MDTuples;
|
||||||
Store.erase(this);
|
Store.erase(cast<MDTuple>(this));
|
||||||
|
|
||||||
Metadata *Old = getOperand(Op);
|
Metadata *Old = getOperand(Op);
|
||||||
setOperand(Op, New);
|
setOperand(Op, New);
|
||||||
@ -549,11 +552,11 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Re-unique the node.
|
// Re-unique the node.
|
||||||
recalculateHash();
|
cast<MDTuple>(this)->recalculateHash();
|
||||||
GenericMDNodeInfo::KeyTy Key(this);
|
MDTupleInfo::KeyTy Key(cast<MDTuple>(this));
|
||||||
auto I = Store.find_as(Key);
|
auto I = Store.find_as(Key);
|
||||||
if (I == Store.end()) {
|
if (I == Store.end()) {
|
||||||
Store.insert(this);
|
Store.insert(cast<MDTuple>(this));
|
||||||
|
|
||||||
if (!isResolved())
|
if (!isResolved())
|
||||||
resolveAfterOperandChange(Old, New);
|
resolveAfterOperandChange(Old, New);
|
||||||
@ -570,7 +573,7 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
|
|||||||
for (unsigned O = 0, E = getNumOperands(); O != E; ++O)
|
for (unsigned O = 0, E = getNumOperands(); O != E; ++O)
|
||||||
setOperand(O, nullptr);
|
setOperand(O, nullptr);
|
||||||
ReplaceableUses->replaceAllUsesWith(*I);
|
ReplaceableUses->replaceAllUsesWith(*I);
|
||||||
delete this;
|
delete cast<MDTuple>(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,9 +583,9 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
|
|||||||
|
|
||||||
MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs,
|
MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs,
|
||||||
bool Insert) {
|
bool Insert) {
|
||||||
auto &Store = Context.pImpl->MDNodeSet;
|
auto &Store = Context.pImpl->MDTuples;
|
||||||
|
|
||||||
GenericMDNodeInfo::KeyTy Key(MDs);
|
MDTupleInfo::KeyTy Key(MDs);
|
||||||
auto I = Store.find_as(Key);
|
auto I = Store.find_as(Key);
|
||||||
if (I != Store.end())
|
if (I != Store.end())
|
||||||
return *I;
|
return *I;
|
||||||
@ -590,14 +593,14 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Coallocate space for the node and Operands together, then placement new.
|
// Coallocate space for the node and Operands together, then placement new.
|
||||||
auto *N = new (MDs.size()) GenericMDNode(Context, MDs, /* AllowRAUW */ true);
|
auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ true);
|
||||||
N->setHash(Key.Hash);
|
N->setHash(Key.Hash);
|
||||||
Store.insert(N);
|
Store.insert(N);
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
MDNode *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
|
MDNode *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
|
||||||
auto *N = new (MDs.size()) GenericMDNode(Context, MDs, /* AllowRAUW */ false);
|
auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ false);
|
||||||
N->storeDistinctInContext();
|
N->storeDistinctInContext();
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
@ -616,9 +619,9 @@ void MDNode::deleteTemporary(MDNode *N) {
|
|||||||
void MDNode::storeDistinctInContext() {
|
void MDNode::storeDistinctInContext() {
|
||||||
assert(!IsDistinctInContext && "Expected newly distinct metadata");
|
assert(!IsDistinctInContext && "Expected newly distinct metadata");
|
||||||
IsDistinctInContext = true;
|
IsDistinctInContext = true;
|
||||||
auto *G = cast<GenericMDNode>(this);
|
auto *T = cast<MDTuple>(this);
|
||||||
G->setHash(0);
|
T->setHash(0);
|
||||||
getContext().pImpl->NonUniquedMDNodes.insert(G);
|
getContext().pImpl->DistinctMDNodes.insert(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
|
void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
|
||||||
@ -630,7 +633,7 @@ void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cast<GenericMDNode>(this)->handleChangedOperand(mutable_begin() + I, New);
|
cast<UniquableMDNode>(this)->handleChangedOperand(mutable_begin() + I, New);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MDNode::setOperand(unsigned I, Metadata *New) {
|
void MDNode::setOperand(unsigned I, Metadata *New) {
|
||||||
|
@ -18,8 +18,8 @@ using namespace llvm;
|
|||||||
|
|
||||||
ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {
|
ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {
|
||||||
if (auto *N = dyn_cast<MDNode>(&MD)) {
|
if (auto *N = dyn_cast<MDNode>(&MD)) {
|
||||||
if (auto *G = dyn_cast<GenericMDNode>(N))
|
if (auto *U = dyn_cast<UniquableMDNode>(N))
|
||||||
return G->ReplaceableUses.get();
|
return U->ReplaceableUses.get();
|
||||||
return cast<MDNodeFwdDecl>(N);
|
return cast<MDNodeFwdDecl>(N);
|
||||||
}
|
}
|
||||||
return dyn_cast<ValueAsMetadata>(&MD);
|
return dyn_cast<ValueAsMetadata>(&MD);
|
||||||
|
@ -260,8 +260,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 *G = dyn_cast<GenericMDNode>(NewMD))
|
if (auto *N = dyn_cast<UniquableMDNode>(NewMD))
|
||||||
G->resolveCycles();
|
N->resolveCycles();
|
||||||
return NewMD;
|
return NewMD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user