summaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/ValueMapper.cpp
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2010-06-22 22:53:21 +0000
committerDevang Patel <dpatel@apple.com>2010-06-22 22:53:21 +0000
commit186b3d260643de5db63c4bab15beceb9edaee396 (patch)
tree20ba5462d067bbef2aa2537eabdc8cd7b3a2d4c6 /lib/Transforms/Utils/ValueMapper.cpp
parent3bf329f49512e633df430c097bfd5bdaa122ba55 (diff)
downloadllvm-186b3d260643de5db63c4bab15beceb9edaee396.tar.gz
llvm-186b3d260643de5db63c4bab15beceb9edaee396.tar.bz2
llvm-186b3d260643de5db63c4bab15beceb9edaee396.tar.xz
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! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106592 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/ValueMapper.cpp')
-rw-r--r--lib/Transforms/Utils/ValueMapper.cpp47
1 files changed, 34 insertions, 13 deletions
diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp
index 87ce631ca6..69e03f8af0 100644
--- a/lib/Transforms/Utils/ValueMapper.cpp
+++ b/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<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 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
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();