From 68ee48f92e35e20ea25172d5e68ad9cab6d6f160 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225921 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/ValueMapper.cpp | 38 ++++++++++++++++++++-------- test/Linker/Inputs/mdlocation.ll | 5 +++- test/Linker/mdlocation.ll | 19 +++++++++----- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index 9ba39e8f3c6..b86de4f196e 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/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/test/Linker/Inputs/mdlocation.ll b/test/Linker/Inputs/mdlocation.ll index b01b459b933..f85c1dc7475 100644 --- a/test/Linker/Inputs/mdlocation.ll +++ b/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/test/Linker/mdlocation.ll b/test/Linker/mdlocation.ll index 0b949d836fe..5ee366cbb43 100644 --- a/test/Linker/mdlocation.ll +++ b/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)