Utils: Handle remapping distinct MDLocations
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Wed, 14 Jan 2015 01:29:32 +0000 (01:29 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Wed, 14 Jan 2015 01:29:32 +0000 (01:29 +0000)
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
test/Linker/Inputs/mdlocation.ll
test/Linker/mdlocation.ll

index 9ba39e8f3c68370d53f3afeb217e3b6697453a39..b86de4f196eceb8cb9174b637522ed00e3e7a24d 100644 (file)
@@ -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<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 @@ 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<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.
index b01b459b933d1ff75b9bc2b469ebbb9ed3024f38..f85c1dc7475db0f130f38b352721760176700e2a 100644 (file)
@@ -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)
index 0b949d836fe0a62ef921efca9901646d14e605af..5ee366cbb433462d85f77d3506819566d1616305 100644 (file)
@@ -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)
 ; 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)