From a5a0f5766a3585a9aff56babe270baa064e7b2f5 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Wed, 14 Jan 2015 01:29:32 +0000 Subject: [PATCH] Utils: Handle remapping distinct MDLocations Part of PR21433. llvm-svn: 225921 --- llvm/lib/Transforms/Utils/ValueMapper.cpp | 38 ++++++++++++++++------- llvm/test/Linker/Inputs/mdlocation.ll | 5 ++- llvm/test/Linker/mdlocation.ll | 19 ++++++++---- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 9ba39e8f3c68..b86de4f196ec 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -185,14 +185,17 @@ static Metadata *cloneMDTuple(const MDTuple *Node, ValueToValueMapTy &VM, ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer, bool IsDistinct) { + // Distinct MDTuples have their own code path. + assert(!IsDistinct && "Unexpected distinct tuple"); + (void)IsDistinct; + SmallVector 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 @@ static Metadata *mapDistinctNode(const UniquableMDNode *Node, ValueMaterializer *Materializer) { assert(Node->isDistinct() && "Expected distinct node"); - // Create the node first so it's available for cyclical references. - SmallVector EmptyOps(Node->getNumOperands()); - MDTuple *NewMD = MDTuple::getDistinct(Node->getContext(), EmptyOps); - mapToMetadata(VM, Node, NewMD); + // Optimization for MDTuples. + if (isa(Node)) { + // Create the node first so it's available for cyclical references. + SmallVector 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 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. diff --git a/llvm/test/Linker/Inputs/mdlocation.ll b/llvm/test/Linker/Inputs/mdlocation.ll index b01b459b933d..f85c1dc7475d 100644 --- a/llvm/test/Linker/Inputs/mdlocation.ll +++ b/llvm/test/Linker/Inputs/mdlocation.ll @@ -1,4 +1,4 @@ -!named = !{!0, !1, !2, !3, !4, !5, !6, !7} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9} !0 = !{} ; Use this as a scope. !1 = !MDLocation(line: 3, column: 7, scope: !0) @@ -8,3 +8,6 @@ !5 = !MDLocation(line: 3, column: 7, scope: !4) !6 = !MDLocation(line: 3, column: 7, scope: !4, inlinedAt: !5) !7 = !MDLocation(line: 3, column: 7, scope: !4, inlinedAt: !6) +; Test distinct nodes. +!8 = distinct !MDLocation(line: 3, column: 7, scope: !0) +!9 = distinct !MDLocation(line: 3, column: 7, scope: !0, inlinedAt: !8) diff --git a/llvm/test/Linker/mdlocation.ll b/llvm/test/Linker/mdlocation.ll index 0b949d836fe0..5ee366cbb433 100644 --- a/llvm/test/Linker/mdlocation.ll +++ b/llvm/test/Linker/mdlocation.ll @@ -2,8 +2,8 @@ ; Test that MDLocations are remapped properly. -; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !0, !1, !2, !3, !8, !9, !10, !11} -!named = !{!0, !1, !2, !3, !4, !5, !6, !7} +; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !0, !1, !2, !3, !10, !11, !12, !13, !14, !15} +!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9} ; CHECK: !0 = !{} ; CHECK-NEXT: !1 = !MDLocation(line: 3, column: 7, scope: !0) @@ -13,10 +13,14 @@ ; CHECK-NEXT: !5 = !MDLocation(line: 3, column: 7, scope: !4) ; CHECK-NEXT: !6 = !MDLocation(line: 3, column: 7, scope: !4, inlinedAt: !5) ; CHECK-NEXT: !7 = !MDLocation(line: 3, column: 7, scope: !4, inlinedAt: !6) -; CHECK-NEXT: !8 = distinct !{} -; CHECK-NEXT: !9 = !MDLocation(line: 3, column: 7, scope: !8) -; CHECK-NEXT: !10 = !MDLocation(line: 3, column: 7, scope: !8, inlinedAt: !9) -; CHECK-NEXT: !11 = !MDLocation(line: 3, column: 7, scope: !8, inlinedAt: !10) +; CHECK-NEXT: !8 = distinct !MDLocation(line: 3, column: 7, scope: !0) +; CHECK-NEXT: !9 = distinct !MDLocation(line: 3, column: 7, scope: !0, inlinedAt: !8) +; CHECK-NEXT: !10 = distinct !{} +; CHECK-NEXT: !11 = !MDLocation(line: 3, column: 7, scope: !10) +; CHECK-NEXT: !12 = !MDLocation(line: 3, column: 7, scope: !10, inlinedAt: !11) +; CHECK-NEXT: !13 = !MDLocation(line: 3, column: 7, scope: !10, inlinedAt: !12) +; CHECK-NEXT: !14 = distinct !MDLocation(line: 3, column: 7, scope: !0) +; CHECK-NEXT: !15 = distinct !MDLocation(line: 3, column: 7, scope: !0, inlinedAt: !14) !0 = !{} ; Use this as a scope. !1 = !MDLocation(line: 3, column: 7, scope: !0) !2 = !MDLocation(line: 3, column: 7, scope: !0, inlinedAt: !1) @@ -25,3 +29,6 @@ !5 = !MDLocation(line: 3, column: 7, scope: !4) !6 = !MDLocation(line: 3, column: 7, scope: !4, inlinedAt: !5) !7 = !MDLocation(line: 3, column: 7, scope: !4, inlinedAt: !6) +; Test distinct nodes. +!8 = distinct !MDLocation(line: 3, column: 7, scope: !0) +!9 = distinct !MDLocation(line: 3, column: 7, scope: !0, inlinedAt: !8)