[llvm-commits] [llvm] r106592 - /llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp

Devang Patel dpatel at apple.com
Tue Jun 22 15:53:21 PDT 2010


Author: dpatel
Date: Tue Jun 22 17:53:21 2010
New Revision: 106592

URL: http://llvm.org/viewvc/llvm-project?rev=106592&view=rev
Log:
If a metadata operand is seeded in value map and the metadata should also be seeded in value map. This is not limited to function local metadata. 

Failure to seed metdata in such cases causes troubles when in a cloned module, metadata from a new module refers to values in old module. Usually this results in mysterious bugpoint crashes. For example,

 Checking to see if we can delete global inits: Unknown constant!
 UNREACHABLE executed at /d/g/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp:904!


Modified:
    llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp

Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=106592&r1=106591&r2=106592&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Tue Jun 22 17:53:21 2010
@@ -21,23 +21,44 @@
 using namespace llvm;
 
 Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
-  Value *&VMSlot = VM[V];
-  if (VMSlot) return VMSlot;      // Does it exist in the map yet?
+  ValueToValueMapTy::iterator VMI = VM.find(V);
+  if (VMI != VM.end()) 
+    return VMI->second;      // Does it exist in the map yet?
   
-  // NOTE: VMSlot can be invalidated by any reference to VM, which can grow the
-  // DenseMap.  This includes any recursive calls to MapValue.
-
-  // Global values and non-function-local metadata do not need to be seeded into
+  // Global values, metadata strings and inline asm do not need to be seeded into
   // the ValueMap if they are using the identity mapping.
-  if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V) ||
-      (isa<MDNode>(V) && !cast<MDNode>(V)->isFunctionLocal()))
-    return VMSlot = const_cast<Value*>(V);
+  if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V)) {
+    VM.insert(std::make_pair(V, const_cast<Value*>(V)));
+    return const_cast<Value*>(V);
+  }
 
   if (const MDNode *MD = dyn_cast<MDNode>(V)) {
+    // Insert a place holder in map to handle mdnode cycles.
+    Value *TmpV = MDString::get(V->getContext(),
+                                std::string("llvm.md.clone.tmp." + VM.size()));
+    VM.insert(std::make_pair(V, MDNode::get(V->getContext(), &TmpV, 1)));
+    
+    bool ReuseMD = true;
     SmallVector<Value*, 4> Elts;
-    for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i)
-      Elts.push_back(MD->getOperand(i) ? MapValue(MD->getOperand(i), VM) : 0);
-    return VM[V] = MDNode::get(V->getContext(), Elts.data(), Elts.size());
+    // If metadata element is mapped to a new value then seed metadata 
+    // in the map.
+    for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
+      if (!MD->getOperand(i))
+        Elts.push_back(0);
+      else {
+        Value *MappedOp = MapValue(MD->getOperand(i), VM);
+        if (MappedOp != MD->getOperand(i))
+          ReuseMD = false;
+        Elts.push_back(MappedOp);
+      }
+    }
+    if (ReuseMD) {
+      VM.insert(std::make_pair(V, const_cast<Value*>(V)));
+      return const_cast<Value*>(V);
+    }
+    MDNode *NewMD = MDNode::get(V->getContext(), Elts.data(), Elts.size());
+    VM.insert(std::make_pair(V, NewMD));
+    return NewMD;
   }
 
   Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
@@ -46,7 +67,7 @@
   if (isa<ConstantInt>(C) || isa<ConstantFP>(C) ||
       isa<ConstantPointerNull>(C) || isa<ConstantAggregateZero>(C) ||
       isa<UndefValue>(C) || isa<MDString>(C))
-    return VMSlot = C;           // Primitive constants map directly
+    return VM[V] = C;           // Primitive constants map directly
   
   if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
     for (User::op_iterator b = CA->op_begin(), i = b, e = CA->op_end();





More information about the llvm-commits mailing list