IR: Assert that resolve() is only called on uniqued nodes, NFC
[oota-llvm.git] / lib / IR / Metadata.cpp
index ab83252bfda338e1711f84d978314185ed3d44e3..8a4710444f34feb5a3d829d1f5b1e7bb68242ff6 100644 (file)
@@ -167,6 +167,11 @@ void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
     return L.second.second < R.second.second;
   });
   for (const auto &Pair : Uses) {
+    // Check that this Ref hasn't disappeared after RAUW (when updating a
+    // previous Ref).
+    if (!UseMap.count(Pair.first))
+      continue;
+
     OwnerTy Owner = Pair.second.first;
     if (!Owner) {
       // Update unowned tracking references directly.
@@ -390,17 +395,16 @@ void MDNode::operator delete(void *Mem) {
   ::operator delete(O);
 }
 
-MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs)
-    : Metadata(ID), Context(Context), NumOperands(MDs.size()),
+MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
+               ArrayRef<Metadata *> MDs)
+    : Metadata(ID, Storage), Context(Context), NumOperands(MDs.size()),
       MDNodeSubclassData(0) {
   for (unsigned I = 0, E = MDs.size(); I != E; ++I)
     setOperand(I, MDs[I]);
-}
 
-bool MDNode::isResolved() const {
-  if (isa<MDNodeFwdDecl>(this))
-    return false;
-  return cast<UniquableMDNode>(this)->isResolved();
+  if (Storage == Temporary)
+    this->Context.makeReplaceable(
+        make_unique<ReplaceableMetadataImpl>(Context));
 }
 
 static bool isOperandUnresolved(Metadata *Op) {
@@ -410,9 +414,9 @@ static bool isOperandUnresolved(Metadata *Op) {
 }
 
 UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID,
-                                 ArrayRef<Metadata *> Vals, bool AllowRAUW)
-    : MDNode(C, ID, Vals) {
-  if (!AllowRAUW)
+                                 StorageType Storage, ArrayRef<Metadata *> Vals)
+    : MDNode(C, ID, Storage, Vals) {
+  if (Storage != Uniqued)
     return;
 
   // Check whether any operands are unresolved, requiring re-uniquing.
@@ -423,15 +427,16 @@ UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID,
   if (!NumUnresolved)
     return;
 
-  ReplaceableUses.reset(new ReplaceableMetadataImpl);
+  this->Context.makeReplaceable(make_unique<ReplaceableMetadataImpl>(C));
   SubclassData32 = NumUnresolved;
 }
 
 void UniquableMDNode::resolve() {
+  assert(Storage == Uniqued && "Expected this to be uniqued");
   assert(!isResolved() && "Expected this to be unresolved");
 
   // Move the map, so that this immediately looks resolved.
-  auto Uses = std::move(ReplaceableUses);
+  auto Uses = Context.takeReplaceableUses();
   SubclassData32 = 0;
   assert(isResolved() && "Expected this to be resolved");
 
@@ -493,8 +498,8 @@ void MDNode::dropAllReferences() {
     setOperand(I, nullptr);
   if (auto *N = dyn_cast<UniquableMDNode>(this))
     if (!N->isResolved()) {
-      N->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);
-      N->ReplaceableUses.reset();
+      N->Context.getReplaceableUses()->resolveAllUses(/* ResolveUsers */ false);
+      (void)N->Context.takeReplaceableUses();
     }
 }
 
@@ -535,9 +540,9 @@ void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {
 
   // Drop uniquing for self-reference cycles.
   if (New == this) {
-    storeDistinctInContext();
     if (!isResolved())
       resolve();
+    storeDistinctInContext();
     return;
   }
 
@@ -557,7 +562,7 @@ void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {
     // dropAllReferences(), but we still need the use-list).
     for (unsigned O = 0, E = getNumOperands(); O != E; ++O)
       setOperand(O, nullptr);
-    ReplaceableUses->replaceAllUsesWith(Uniqued);
+    Context.getReplaceableUses()->replaceAllUsesWith(Uniqued);
     deleteAsSubclass();
     return;
   }
@@ -613,14 +618,14 @@ MDTuple *MDTuple::getImpl(LLVMContext &Context, ArrayRef<Metadata *> MDs,
     return nullptr;
 
   // Coallocate space for the node and Operands together, then placement new.
-  auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ true);
+  auto *N = new (MDs.size()) MDTuple(Context, Uniqued, MDs);
   N->setHash(Key.Hash);
   Store.insert(N);
   return N;
 }
 
 MDTuple *MDTuple::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
-  auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ false);
+  auto *N = new (MDs.size()) MDTuple(Context, Distinct, MDs);
   N->storeDistinctInContext();
   return N;
 }
@@ -640,28 +645,29 @@ MDTuple *MDTuple::uniquifyImpl() {
 
 void MDTuple::eraseFromStoreImpl() { getContext().pImpl->MDTuples.erase(this); }
 
-MDLocation::MDLocation(LLVMContext &C, unsigned Line, unsigned Column,
-                       ArrayRef<Metadata *> MDs, bool AllowRAUW)
-    : UniquableMDNode(C, MDLocationKind, MDs, AllowRAUW) {
+MDLocation::MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
+                       unsigned Column, ArrayRef<Metadata *> MDs)
+    : UniquableMDNode(C, MDLocationKind, Storage, MDs) {
   assert((MDs.size() == 1 || MDs.size() == 2) &&
          "Expected a scope and optional inlined-at");
 
   // Set line and column.
   assert(Line < (1u << 24) && "Expected 24-bit line");
-  assert(Column < (1u << 8) && "Expected 8-bit column");
+  assert(Column < (1u << 16) && "Expected 16-bit column");
 
   MDNodeSubclassData = Line;
   SubclassData16 = Column;
 }
 
-MDLocation *MDLocation::constructHelper(LLVMContext &Context, unsigned Line,
+MDLocation *MDLocation::constructHelper(LLVMContext &Context,
+                                        StorageType Storage, unsigned Line,
                                         unsigned Column, Metadata *Scope,
-                                        Metadata *InlinedAt, bool AllowRAUW) {
+                                        Metadata *InlinedAt) {
   SmallVector<Metadata *, 2> Ops;
   Ops.push_back(Scope);
   if (InlinedAt)
     Ops.push_back(InlinedAt);
-  return new (Ops.size()) MDLocation(Context, Line, Column, Ops, AllowRAUW);
+  return new (Ops.size()) MDLocation(Context, Storage, Line, Column, Ops);
 }
 
 static void adjustLine(unsigned &Line) {
@@ -671,8 +677,8 @@ static void adjustLine(unsigned &Line) {
 }
 
 static void adjustColumn(unsigned &Column) {
-  // Set to unknown on overflow.  Still use 8 bits for now.
-  if (Column >= (1u << 8))
+  // Set to unknown on overflow.  We only have 16 bits to play with here.
+  if (Column >= (1u << 16))
     Column = 0;
 }
 
@@ -692,8 +698,7 @@ MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line,
   if (!ShouldCreate)
     return nullptr;
 
-  auto *N = constructHelper(Context, Line, Column, Scope, InlinedAt,
-                            /* AllowRAUW */ true);
+  auto *N = constructHelper(Context, Uniqued, Line, Column, Scope, InlinedAt);
   Store.insert(N);
   return N;
 }
@@ -705,8 +710,7 @@ MDLocation *MDLocation::getDistinct(LLVMContext &Context, unsigned Line,
   adjustLine(Line);
   adjustColumn(Column);
 
-  auto *N = constructHelper(Context, Line, Column, Scope, InlinedAt,
-                            /* AllowRAUW */ false);
+  auto *N = constructHelper(Context, Distinct, Line, Column, Scope, InlinedAt);
   N->storeDistinctInContext();
   return N;
 }
@@ -735,8 +739,8 @@ MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context,
 void MDNode::deleteTemporary(MDNode *N) { delete cast<MDNodeFwdDecl>(N); }
 
 void UniquableMDNode::storeDistinctInContext() {
-  assert(!IsDistinctInContext && "Expected newly distinct metadata");
-  IsDistinctInContext = true;
+  assert(isResolved() && "Expected resolved nodes");
+  Storage = Distinct;
   if (auto *T = dyn_cast<MDTuple>(this))
     T->setHash(0);
   getContext().pImpl->DistinctMDNodes.insert(this);
@@ -746,7 +750,7 @@ void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
   if (getOperand(I) == New)
     return;
 
-  if (isDistinct()) {
+  if (!isUniqued()) {
     setOperand(I, New);
     return;
   }