From 87f75f75bef3b24c0ee5092d02c67341d4ea399b Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Tue, 22 Jun 2010 22:53:21 +0000 Subject: [PATCH] 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! llvm-svn: 106592 --- llvm/lib/Transforms/Utils/ValueMapper.cpp | 47 ++++++++++++++++------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 87ce631ca626..69e03f8af049 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -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(V) || isa(V) || isa(V) || - (isa(V) && !cast(V)->isFunctionLocal())) - return VMSlot = const_cast(V); + if (isa(V) || isa(V) || isa(V)) { + VM.insert(std::make_pair(V, const_cast(V))); + return const_cast(V); + } if (const MDNode *MD = dyn_cast(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 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(V))); + return const_cast(V); + } + MDNode *NewMD = MDNode::get(V->getContext(), Elts.data(), Elts.size()); + VM.insert(std::make_pair(V, NewMD)); + return NewMD; } Constant *C = const_cast(dyn_cast(V)); @@ -46,7 +67,7 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) { if (isa(C) || isa(C) || isa(C) || isa(C) || isa(C) || isa(C)) - return VMSlot = C; // Primitive constants map directly + return VM[V] = C; // Primitive constants map directly if (ConstantArray *CA = dyn_cast(C)) { for (User::op_iterator b = CA->op_begin(), i = b, e = CA->op_end();