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
This commit is contained in:
Dan Gohman 2010-08-24 17:10:10 +00:00
parent 92b651fb19
commit 4ce307f963

View File

@ -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 // NOTE: VMSlot can be invalidated by any reference to VM, which can grow the
// DenseMap. This includes any recursive calls to MapValue. // DenseMap. This includes any recursive calls to MapValue.
// Global values and non-function-local metadata do not need to be seeded into // Global values do not need to be seeded into the VM if they
// the VM if they are using the identity mapping. // are using the identity mapping.
if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V) || if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V))
(isa<MDNode>(V) && !cast<MDNode>(V)->isFunctionLocal()))
return VMSlot = const_cast<Value*>(V); return VMSlot = const_cast<Value*>(V);
if (const MDNode *MD = dyn_cast<MDNode>(V)) { if (const MDNode *MD = dyn_cast<MDNode>(V)) {
SmallVector<Value*, 4> Elts; // Start by assuming that we'll use the identity mapping.
for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) VMSlot = const_cast<Value*>(V);
Elts.push_back(MD->getOperand(i) ? MapValue(MD->getOperand(i), VM) : 0);
return VM[V] = MDNode::get(V->getContext(), Elts.data(), Elts.size()); // 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)); Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));