aboutsummaryrefslogtreecommitdiffstats
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
commit8e38b1d98fd4d6eff10a3f555aa208f12a49dd89 (patch)
tree20ba5462d067bbef2aa2537eabdc8cd7b3a2d4c6
parent761994daf5c086ce004e7e2802e18dd2d41686a4 (diff)
downloadexternal_llvm-8e38b1d98fd4d6eff10a3f555aa208f12a49dd89.zip
external_llvm-8e38b1d98fd4d6eff10a3f555aa208f12a49dd89.tar.gz
external_llvm-8e38b1d98fd4d6eff10a3f555aa208f12a49dd89.tar.bz2
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
-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 87ce631..69e03f8 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();