aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Utils/ValueMapper.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-08-24 17:10:10 +0000
committerDan Gohman <gohman@apple.com>2010-08-24 17:10:10 +0000
commit0171e9aa81beb968ff9e3f009b94a336ba4178d6 (patch)
treeec32599a7144eb2b2784d1fc75ec38e148d00872 /lib/Transforms/Utils/ValueMapper.cpp
parente334b9ceb739cf5bf51edd2faf327ccfaab3ded1 (diff)
downloadexternal_llvm-0171e9aa81beb968ff9e3f009b94a336ba4178d6.zip
external_llvm-0171e9aa81beb968ff9e3f009b94a336ba4178d6.tar.gz
external_llvm-0171e9aa81beb968ff9e3f009b94a336ba4178d6.tar.bz2
MapValue support for MDNodes. This is similar to r109117, except
that it avoids a lot of unnecessary cloning by avoiding remapping MDNode cycles when none of the nodes in the cycle actually need to be remapped. Also it uses the new temporary MDNode mechanism. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111922 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/ValueMapper.cpp')
-rw-r--r--lib/Transforms/Utils/ValueMapper.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp
index 3f6a90c..7f61c25 100644
--- a/lib/Transforms/Utils/ValueMapper.cpp
+++ b/lib/Transforms/Utils/ValueMapper.cpp
@@ -27,17 +27,36 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM) {
// 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
- // the VM if they are using the identity mapping.
- if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V) ||
- (isa<MDNode>(V) && !cast<MDNode>(V)->isFunctionLocal()))
+ // Global values do not need to be seeded into the VM if they
+ // are using the identity mapping.
+ if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V))
return VMSlot = const_cast<Value*>(V);
if (const MDNode *MD = dyn_cast<MDNode>(V)) {
- 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());
+ // Start by assuming that we'll use the identity mapping.
+ VMSlot = const_cast<Value*>(V);
+
+ // Check all operands to see if any need to be remapped.
+ for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
+ Value *OP = MD->getOperand(i);
+ if (!OP || MapValue(OP, VM) == OP) continue;
+
+ // Ok, at least one operand needs remapping.
+ MDNode *Dummy = MDNode::getTemporary(V->getContext(), 0, 0);
+ VM[V] = Dummy;
+ SmallVector<Value*, 4> Elts;
+ Elts.reserve(MD->getNumOperands());
+ for (i = 0; i != e; ++i)
+ Elts.push_back(MD->getOperand(i) ?
+ MapValue(MD->getOperand(i), VM) : 0);
+ MDNode *NewMD = MDNode::get(V->getContext(), Elts.data(), Elts.size());
+ Dummy->replaceAllUsesWith(NewMD);
+ MDNode::deleteTemporary(Dummy);
+ return VM[V] = NewMD;
+ }
+
+ // No operands needed remapping; keep the identity map.
+ return const_cast<Value*>(V);
}
Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));