[llvm] r223829 - IR: Metadata/Value split: RAUW in a deterministic order

Duncan P. N. Exon Smith dexonsmith at apple.com
Tue Dec 9 13:12:56 PST 2014


Author: dexonsmith
Date: Tue Dec  9 15:12:56 2014
New Revision: 223829

URL: http://llvm.org/viewvc/llvm-project?rev=223829&view=rev
Log:
IR: Metadata/Value split: RAUW in a deterministic order

RAUW in a deterministic order to try to recover the hexagon bot [1],
whose tests started failing once my GCC fixes were in for r223802.

Otherwise, I'm not sure why tests would fail there and not here.

[1]: http://lab.llvm.org:8011/builders/llvm-hexagon-elf/builds/13426

Modified:
    llvm/trunk/include/llvm/IR/Metadata.h
    llvm/trunk/lib/IR/Metadata.cpp

Modified: llvm/trunk/include/llvm/IR/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=223829&r1=223828&r2=223829&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.h (original)
+++ llvm/trunk/include/llvm/IR/Metadata.h Tue Dec  9 15:12:56 2014
@@ -141,9 +141,11 @@ public:
   typedef MetadataTracking::OwnerTy OwnerTy;
 
 private:
-  SmallDenseMap<void *, OwnerTy, 4> UseMap;
+  uint64_t NextIndex;
+  SmallDenseMap<void *, std::pair<OwnerTy, uint64_t>, 4> UseMap;
 
 public:
+  ReplaceableMetadataImpl() : NextIndex(0) {}
   ~ReplaceableMetadataImpl() {
     assert(UseMap.empty() && "Cannot destroy in-use replaceable metadata");
   }

Modified: llvm/trunk/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=223829&r1=223828&r2=223829&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Metadata.cpp (original)
+++ llvm/trunk/lib/IR/Metadata.cpp Tue Dec  9 15:12:56 2014
@@ -121,9 +121,14 @@ void MetadataAsValue::untrack() {
 }
 
 void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) {
-  bool WasInserted = UseMap.insert(std::make_pair(Ref, Owner)).second;
+  bool WasInserted =
+      UseMap.insert(std::make_pair(Ref, std::make_pair(Owner, NextIndex)))
+          .second;
   (void)WasInserted;
   assert(WasInserted && "Expected to add a reference");
+
+  ++NextIndex;
+  assert(NextIndex != 0 && "Unexpected overflow");
 }
 
 void ReplaceableMetadataImpl::dropRef(void *Ref) {
@@ -136,15 +141,17 @@ void ReplaceableMetadataImpl::moveRef(vo
                                       const Metadata &MD) {
   auto I = UseMap.find(Ref);
   assert(I != UseMap.end() && "Expected to move a reference");
-  OwnerTy Owner = I->second;
+  auto OwnerAndIndex = I->second;
   UseMap.erase(I);
-  addRef(New, Owner);
+  bool WasInserted = UseMap.insert(std::make_pair(New, OwnerAndIndex)).second;
+  (void)WasInserted;
+  assert(WasInserted && "Expected to add a reference");
 
   // Check that the references are direct if there's no owner.
   (void)MD;
-  assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
+  assert((OwnerAndIndex.first || *static_cast<Metadata **>(Ref) == &MD) &&
          "Reference without owner must be direct");
-  assert((Owner || *static_cast<Metadata **>(New) == &MD) &&
+  assert((OwnerAndIndex.first || *static_cast<Metadata **>(New) == &MD) &&
          "Reference without owner must be direct");
 }
 
@@ -155,9 +162,14 @@ void ReplaceableMetadataImpl::replaceAll
     return;
 
   // Copy out uses since UseMap will get touched below.
-  SmallVector<std::pair<void *, OwnerTy>, 8> Uses(UseMap.begin(), UseMap.end());
+  typedef std::pair<void *, std::pair<OwnerTy, uint64_t>> UseTy;
+  SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end());
+  std::sort(Uses.begin(), Uses.end(), [](const UseTy &L, const UseTy &R) {
+    return L.second.second < R.second.second;
+  });
   for (const auto &Pair : Uses) {
-    if (!Pair.second) {
+    OwnerTy Owner = Pair.second.first;
+    if (!Owner) {
       // Update unowned tracking references directly.
       Metadata *&Ref = *static_cast<Metadata **>(Pair.first);
       Ref = MD;
@@ -167,17 +179,17 @@ void ReplaceableMetadataImpl::replaceAll
     }
 
     // Check for MetadataAsValue.
-    if (Pair.second.is<MetadataAsValue *>()) {
-      Pair.second.get<MetadataAsValue *>()->handleChangedMetadata(MD);
+    if (Owner.is<MetadataAsValue *>()) {
+      Owner.get<MetadataAsValue *>()->handleChangedMetadata(MD);
       continue;
     }
 
     // There's a Metadata owner -- dispatch.
-    Metadata *Owner = Pair.second.get<Metadata *>();
-    switch (Owner->getMetadataID()) {
+    Metadata *OwnerMD = Owner.get<Metadata *>();
+    switch (OwnerMD->getMetadataID()) {
 #define HANDLE_METADATA_LEAF(CLASS)                                            \
   case Metadata::CLASS##Kind:                                                  \
-    cast<CLASS>(Owner)->handleChangedOperand(Pair.first, MD);                  \
+    cast<CLASS>(OwnerMD)->handleChangedOperand(Pair.first, MD);                \
     continue;
 #include "llvm/IR/Metadata.def"
     default:
@@ -197,23 +209,28 @@ void ReplaceableMetadataImpl::resolveAll
   }
 
   // Copy out uses since UseMap could get touched below.
-  SmallVector<std::pair<void *, OwnerTy>, 8> Uses(UseMap.begin(), UseMap.end());
+  typedef std::pair<void *, std::pair<OwnerTy, uint64_t>> UseTy;
+  SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end());
+  std::sort(Uses.begin(), Uses.end(), [](const UseTy &L, const UseTy &R) {
+    return L.second.second < R.second.second;
+  });
   UseMap.clear();
   for (const auto &Pair : Uses) {
-    if (!Pair.second)
+    auto Owner = Pair.second.first;
+    if (!Owner)
       continue;
-    if (Pair.second.is<MetadataAsValue *>())
+    if (Owner.is<MetadataAsValue *>())
       continue;
 
     // Resolve GenericMDNodes that point at this.
-    auto *Owner = dyn_cast<GenericMDNode>(Pair.second.get<Metadata *>());
-    if (!Owner)
+    auto *OwnerMD = dyn_cast<GenericMDNode>(Owner.get<Metadata *>());
+    if (!OwnerMD)
       continue;
-    if (Owner->isResolved())
+    if (OwnerMD->isResolved())
       continue;
-    Owner->decrementUnresolvedOperands();
-    if (!Owner->hasUnresolvedOperands())
-      Owner->resolve();
+    OwnerMD->decrementUnresolvedOperands();
+    if (!OwnerMD->hasUnresolvedOperands())
+      OwnerMD->resolve();
   }
 }
 





More information about the llvm-commits mailing list