enum MetadataKind {
MDTupleKind,
MDLocationKind,
- MDNodeFwdDeclKind,
ConstantAsMetadataKind,
LocalAsMetadataKind,
MDStringKind
}
~Metadata() {}
- /// \brief Store this in a big non-uniqued untyped bucket.
- bool isStoredDistinctInContext() const { return Storage == Distinct; }
-
/// \brief Default handling of a changed operand, which asserts.
///
/// If subclasses pass themselves in as owners to a tracking node reference,
MDOperand *mutable_end() { return reinterpret_cast<MDOperand *>(this); }
public:
- static inline MDNode *get(LLVMContext &Context, ArrayRef<Metadata *> MDs);
- static inline MDNode *getIfExists(LLVMContext &Context,
- ArrayRef<Metadata *> MDs);
- static inline MDNode *getDistinct(LLVMContext &Context,
- ArrayRef<Metadata *> MDs);
-
- /// \brief Return a temporary MDNode
- ///
- /// For use in constructing cyclic MDNode structures. A temporary MDNode is
- /// not uniqued, may be RAUW'd, and must be manually deleted with
- /// deleteTemporary.
- static MDNodeFwdDecl *getTemporary(LLVMContext &Context,
+ static inline MDTuple *get(LLVMContext &Context, ArrayRef<Metadata *> MDs);
+ static inline MDTuple *getIfExists(LLVMContext &Context,
ArrayRef<Metadata *> MDs);
+ static inline MDTuple *getDistinct(LLVMContext &Context,
+ ArrayRef<Metadata *> MDs);
+ static inline MDTuple *getTemporary(LLVMContext &Context,
+ ArrayRef<Metadata *> MDs);
/// \brief Deallocate a node created by getTemporary.
///
bool isDistinct() const { return Storage == Distinct; }
bool isTemporary() const { return Storage == Temporary; }
+ /// \brief RAUW a temporary.
+ ///
+ /// \pre \a isTemporary() must be \c true.
+ void replaceAllUsesWith(Metadata *MD) {
+ assert(isTemporary() && "Expected temporary node");
+ assert(!isResolved() && "Expected RAUW support");
+ Context.getReplaceableUses()->replaceAllUsesWith(MD);
+ }
+
protected:
/// \brief Set an operand.
///
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTupleKind ||
- MD->getMetadataID() == MDLocationKind ||
- MD->getMetadataID() == MDNodeFwdDeclKind;
+ MD->getMetadataID() == MDLocationKind;
}
/// \brief Check whether MDNode is a vtable access.
/// 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 operands are an instance of \a
-/// MDNodeFwdDecl (or another unresolved \a UniquableMDNode, which
-/// indicates an \a MDNodeFwdDecl in its path), the node itself will be
-/// unresolved. As soon as all operands become resolved, it will drop
-/// RAUW support permanently.
+/// 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 when each \a MDNodeFwdDecl
-/// has been removed.
+/// 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;
~UniquableMDNode() {}
void storeDistinctInContext();
+ template <class T, class StoreT>
+ static T *storeImpl(T *N, StorageType Storage, StoreT &Store);
public:
static bool classof(const Metadata *MD) {
/// Once all forward declarations have been resolved, force cycles to be
/// resolved.
///
- /// \pre No operands (or operands' operands, etc.) are \a MDNodeFwdDecl.
+ /// \pre No operands (or operands' operands, etc.) have \a isTemporary().
void resolveCycles();
private:
friend class LLVMContextImpl;
friend class UniquableMDNode;
- MDTuple(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Vals)
- : UniquableMDNode(C, MDTupleKind, Storage, Vals) {}
+ MDTuple(LLVMContext &C, StorageType Storage, unsigned Hash,
+ ArrayRef<Metadata *> Vals)
+ : UniquableMDNode(C, MDTupleKind, Storage, Vals) {
+ setHash(Hash);
+ }
~MDTuple() { dropAllReferences(); }
void setHash(unsigned Hash) { MDNodeSubclassData = Hash; }
void recalculateHash();
static MDTuple *getImpl(LLVMContext &Context, ArrayRef<Metadata *> MDs,
- bool ShouldCreate);
+ StorageType Storage, bool ShouldCreate = true);
public:
/// \brief Get the hash, if any.
unsigned getHash() const { return MDNodeSubclassData; }
static MDTuple *get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
- return getImpl(Context, MDs, /* ShouldCreate */ true);
+ return getImpl(Context, MDs, Uniqued);
}
static MDTuple *getIfExists(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
- return getImpl(Context, MDs, /* ShouldCreate */ false);
+ return getImpl(Context, MDs, Uniqued, /* ShouldCreate */ false);
}
/// \brief Return a distinct node.
///
/// Return a distinct node -- i.e., a node that is not uniqued.
- static MDTuple *getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs);
+ static MDTuple *getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+ return getImpl(Context, MDs, Distinct);
+ }
+
+ /// \brief Return a temporary node.
+ ///
+ /// For use in constructing cyclic MDNode structures. A temporary MDNode is
+ /// not uniqued, may be RAUW'd, and must be manually deleted with
+ /// deleteTemporary.
+ static MDTuple *getTemporary(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+ return getImpl(Context, MDs, Temporary);
+ }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDTupleKind;
void eraseFromStoreImpl();
};
-MDNode *MDNode::get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+MDTuple *MDNode::get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
return MDTuple::get(Context, MDs);
}
-MDNode *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+MDTuple *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
return MDTuple::getIfExists(Context, MDs);
}
-MDNode *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+MDTuple *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
return MDTuple::getDistinct(Context, MDs);
}
+MDTuple *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
+ return MDTuple::getTemporary(Context, MDs);
+}
/// \brief Debug location.
///
unsigned Column, ArrayRef<Metadata *> MDs);
~MDLocation() { dropAllReferences(); }
- static MDLocation *constructHelper(LLVMContext &Context, StorageType Storage,
- unsigned Line, unsigned Column,
- Metadata *Scope, Metadata *InlinedAt);
-
static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
unsigned Column, Metadata *Scope,
- Metadata *InlinedAt, bool ShouldCreate);
+ Metadata *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true);
// Disallow replacing operands.
void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION;
public:
static MDLocation *get(LLVMContext &Context, unsigned Line, unsigned Column,
Metadata *Scope, Metadata *InlinedAt = nullptr) {
- return getImpl(Context, Line, Column, Scope, InlinedAt,
- /* ShouldCreate */ true);
+ return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued);
}
static MDLocation *getIfExists(LLVMContext &Context, unsigned Line,
unsigned Column, Metadata *Scope,
Metadata *InlinedAt = nullptr) {
- return getImpl(Context, Line, Column, Scope, InlinedAt,
+ return getImpl(Context, Line, Column, Scope, InlinedAt, Uniqued,
/* ShouldCreate */ false);
}
static MDLocation *getDistinct(LLVMContext &Context, unsigned Line,
unsigned Column, Metadata *Scope,
- Metadata *InlinedAt = nullptr);
+ Metadata *InlinedAt = nullptr) {
+ return getImpl(Context, Line, Column, Scope, InlinedAt, Distinct);
+ }
unsigned getLine() const { return MDNodeSubclassData; }
unsigned getColumn() const { return SubclassData16; }
void eraseFromStoreImpl();
};
-/// \brief Forward declaration of metadata.
-///
-/// Forward declaration of metadata, in the form of a basic tuple. Unlike \a
-/// MDTuple, this class has full support for RAUW, is not owned, is not
-/// uniqued, and is suitable for forward references.
-class MDNodeFwdDecl : public MDNode {
- friend class Metadata;
-
- MDNodeFwdDecl(LLVMContext &C, ArrayRef<Metadata *> Vals)
- : MDNode(C, MDNodeFwdDeclKind, Temporary, Vals) {}
-
-public:
- ~MDNodeFwdDecl() { dropAllReferences(); }
-
- // MSVC doesn't see the alternative: "using MDNode::operator delete".
- void operator delete(void *Mem) { MDNode::operator delete(Mem); }
-
- static MDNodeFwdDecl *get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
- return new (MDs.size()) MDNodeFwdDecl(Context, MDs);
- }
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDNodeFwdDeclKind;
- }
-
- void replaceAllUsesWith(Metadata *MD) {
- assert(Context.hasReplaceableUses() && "Expected RAUW support");
- Context.getReplaceableUses()->replaceAllUsesWith(MD);
- }
-};
-
//===----------------------------------------------------------------------===//
/// \brief A tuple of MDNodes.
///