ValueMapper: Resolve uniquing cycles more aggressively
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 7 Aug 2015 00:44:55 +0000 (00:44 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Fri, 7 Aug 2015 00:44:55 +0000 (00:44 +0000)
As a follow-up to r244181, resolve uniquing cycles underneath distinct
nodes on the fly.  This prevents uniquing cycles in early operands from
affecting later operands.  It also removes an iteration through distinct
nodes' operands.

No real functional change here, just more prompt resolution of temporary
nodes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244302 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/ValueMapper.cpp

index 85c751f311da4ca651890c1db02d64ecccfc5c2b..c9e474da8af4cb2785d010e26f575335d402dbf0 100644 (file)
@@ -191,12 +191,18 @@ static void resolveCycles(Metadata *MD) {
 }
 
 /// Remap the operands of an MDNode.
+///
+/// If \c Node is temporary, uniquing cycles are ignored.  If \c Node is
+/// distinct, uniquing cycles are resolved as they're found.
+///
+/// \pre \c Node.isDistinct() or \c Node.isTemporary().
 static bool remapOperands(MDNode &Node,
                           SmallVectorImpl<MDNode *> &DistinctWorklist,
                           ValueToValueMapTy &VM, RemapFlags Flags,
                           ValueMapTypeRemapper *TypeMapper,
                           ValueMaterializer *Materializer) {
   assert(!Node.isUniqued() && "Expected temporary or distinct node");
+  const bool IsDistinct = Node.isDistinct();
 
   bool AnyChanged = false;
   for (unsigned I = 0, E = Node.getNumOperands(); I != E; ++I) {
@@ -206,6 +212,11 @@ static bool remapOperands(MDNode &Node,
     if (Old != New) {
       AnyChanged = true;
       Node.replaceOperandWith(I, New);
+
+      // Resolve uniquing cycles underneath distinct nodes on the fly so they
+      // don't infect later operands.
+      if (IsDistinct)
+        resolveCycles(New);
     }
   }
 
@@ -332,15 +343,9 @@ Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
   resolveCycles(NewMD);
 
   // Remap the operands of distinct MDNodes.
-  while (!DistinctWorklist.empty()) {
-    auto *N = DistinctWorklist.pop_back_val();
-
-    // If an operand changes, then it may be involved in a uniquing cycle.
-    if (remapOperands(*N, DistinctWorklist, VM, Flags, TypeMapper,
-                      Materializer))
-      for (Metadata *MD : N->operands())
-        resolveCycles(MD);
-  }
+  while (!DistinctWorklist.empty())
+    remapOperands(*DistinctWorklist.pop_back_val(), DistinctWorklist, VM, Flags,
+                  TypeMapper, Materializer);
 
   return NewMD;
 }