Utils: Handle remapping distinct MDLocations
Part of PR21433.
llvm-svn: 225921
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 9ba39e8..b86de4f 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -185,14 +185,17 @@
ValueMapTypeRemapper *TypeMapper,
ValueMaterializer *Materializer,
bool IsDistinct) {
+ // Distinct MDTuples have their own code path.
+ assert(!IsDistinct && "Unexpected distinct tuple");
+ (void)IsDistinct;
+
SmallVector<Metadata *, 4> Elts;
Elts.reserve(Node->getNumOperands());
for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I)
Elts.push_back(mapMetadataOp(Node->getOperand(I), VM, Flags, TypeMapper,
Materializer));
- return (IsDistinct ? MDTuple::getDistinct : MDTuple::get)(Node->getContext(),
- Elts);
+ return MDTuple::get(Node->getContext(), Elts);
}
static Metadata *cloneMDLocation(const MDLocation *Node, ValueToValueMapTy &VM,
@@ -230,17 +233,30 @@
ValueMaterializer *Materializer) {
assert(Node->isDistinct() && "Expected distinct node");
- // Create the node first so it's available for cyclical references.
- SmallVector<Metadata *, 4> EmptyOps(Node->getNumOperands());
- MDTuple *NewMD = MDTuple::getDistinct(Node->getContext(), EmptyOps);
- mapToMetadata(VM, Node, NewMD);
+ // Optimization for MDTuples.
+ if (isa<MDTuple>(Node)) {
+ // Create the node first so it's available for cyclical references.
+ SmallVector<Metadata *, 4> EmptyOps(Node->getNumOperands());
+ MDTuple *NewMD = MDTuple::getDistinct(Node->getContext(), EmptyOps);
+ mapToMetadata(VM, Node, NewMD);
- // Fix the operands.
- for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I)
- NewMD->replaceOperandWith(I, mapMetadataOp(Node->getOperand(I), VM, Flags,
- TypeMapper, Materializer));
+ // Fix the operands.
+ for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I)
+ NewMD->replaceOperandWith(I, mapMetadataOp(Node->getOperand(I), VM, Flags,
+ TypeMapper, Materializer));
- return NewMD;
+ return NewMD;
+ }
+
+ // In general we need a dummy node, since whether the operands are null can
+ // affect the size of the node.
+ std::unique_ptr<MDNodeFwdDecl> Dummy(
+ MDNode::getTemporary(Node->getContext(), None));
+ mapToMetadata(VM, Node, Dummy.get());
+ Metadata *NewMD = cloneMDNode(Node, VM, Flags, TypeMapper, Materializer,
+ /* IsDistinct */ true);
+ Dummy->replaceAllUsesWith(NewMD);
+ return mapToMetadata(VM, Node, NewMD);
}
/// \brief Check whether a uniqued node needs to be remapped.