IR: Remove MDNodeFwdDecl
[oota-llvm.git] / include / llvm / IR / Metadata.h
index f6a3b7a9b79c796dc98d21c30d0750e05ffb1aba..6f02ee1e70403f54d5584a8c09bbbd1fe205cbac 100644 (file)
@@ -61,7 +61,6 @@ public:
   enum MetadataKind {
     MDTupleKind,
     MDLocationKind,
-    MDNodeFwdDeclKind,
     ConstantAsMetadataKind,
     LocalAsMetadataKind,
     MDStringKind
@@ -73,9 +72,6 @@ protected:
   }
   ~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,
@@ -696,19 +692,13 @@ protected:
   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.
   ///
@@ -721,12 +711,31 @@ public:
   void replaceOperandWith(unsigned I, Metadata *New);
 
   /// \brief Check if node is fully resolved.
-  bool isResolved() const;
+  ///
+  /// If \a isTemporary(), this always returns \c false; if \a isDistinct(),
+  /// this always returns \c true.
+  ///
+  /// If \a isUniqued(), returns \c true if this has already dropped RAUW
+  /// support (because all operands are resolved).
+  ///
+  /// As forward declarations are resolved, their containers should get
+  /// resolved automatically.  However, if this (or one of its operands) is
+  /// involved in a cycle, \a resolveCycles() needs to be called explicitly.
+  bool isResolved() const { return !Context.hasReplaceableUses(); }
 
   bool isUniqued() const { return Storage == Uniqued; }
   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.
   ///
@@ -756,8 +765,7 @@ public:
   /// \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.
@@ -778,16 +786,15 @@ public:
 /// 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;
@@ -804,6 +811,8 @@ protected:
   ~UniquableMDNode() {}
 
   void storeDistinctInContext();
+  template <class T, class StoreT>
+  static T *storeImpl(T *N, StorageType Storage, StoreT &Store);
 
 public:
   static bool classof(const Metadata *MD) {
@@ -811,22 +820,12 @@ public:
            MD->getMetadataID() == MDLocationKind;
   }
 
-  /// \brief Check whether any operands are forward declarations.
-  ///
-  /// Returns \c true as long as any operands (or their operands, etc.) are \a
-  /// MDNodeFwdDecl.
-  ///
-  /// As forward declarations are resolved, their containers should get
-  /// resolved automatically.  However, if this (or one of its operands) is
-  /// involved in a cycle, \a resolveCycles() needs to be called explicitly.
-  bool isResolved() const { return !Context.hasReplaceableUses(); }
-
   /// \brief Resolve cycles.
   ///
   /// 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:
@@ -849,31 +848,45 @@ class MDTuple : public UniquableMDNode {
   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;
@@ -884,15 +897,18 @@ private:
   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.
 ///
@@ -905,13 +921,10 @@ class MDLocation : public UniquableMDNode {
              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;
@@ -919,18 +932,19 @@ class MDLocation : public UniquableMDNode {
 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; }
@@ -950,37 +964,6 @@ private:
   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.
 ///