[llvm] r258728 - [ThinLTO] Find all needed metadata when linking metadata as postpass

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 25 14:04:56 PST 2016


Author: tejohnson
Date: Mon Jan 25 16:04:56 2016
New Revision: 258728

URL: http://llvm.org/viewvc/llvm-project?rev=258728&view=rev
Log:
[ThinLTO] Find all needed metadata when linking metadata as postpass

For metadata postpass linking, after importing all functions, we need
to recursively walk through any nodes reached via imported functions to
locate needed subprogram metadata. Some might only be reached indirectly
via the variable list for an inlined function.

Modified:
    llvm/trunk/lib/Linker/IRMover.cpp
    llvm/trunk/test/Linker/thinlto_funcimport_debug.ll

Modified: llvm/trunk/lib/Linker/IRMover.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/IRMover.cpp?rev=258728&r1=258727&r2=258728&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/IRMover.cpp (original)
+++ llvm/trunk/lib/Linker/IRMover.cpp Mon Jan 25 16:04:56 2016
@@ -501,6 +501,11 @@ class IRLinker {
   /// in an imported function.
   void findNeededSubprograms();
 
+  /// Recursive helper for findNeededSubprograms to locate any DISubprogram
+  /// reached from the given Node, marking any found as needed.
+  void findReachedSubprograms(const MDNode *Node,
+                              SmallPtrSet<const MDNode *, 16> &Visited);
+
   /// The value mapper leaves nulls in the list of subprograms for any
   /// in the UnneededSubprograms map. Strip those out after metadata linking.
   void stripNullSubprograms();
@@ -1194,6 +1199,21 @@ bool IRLinker::linkGlobalValueBody(Globa
   return false;
 }
 
+void IRLinker::findReachedSubprograms(
+    const MDNode *Node, SmallPtrSet<const MDNode *, 16> &Visited) {
+  if (!Visited.insert(Node).second)
+    return;
+  DISubprogram *SP = getDISubprogram(Node);
+  if (SP)
+    UnneededSubprograms.erase(SP);
+  for (auto &Op : Node->operands()) {
+    const MDNode *OpN = dyn_cast_or_null<MDNode>(Op.get());
+    if (!OpN)
+      continue;
+    findReachedSubprograms(OpN, Visited);
+  }
+}
+
 void IRLinker::findNeededSubprograms() {
   // Track unneeded nodes to make it simpler to handle the case
   // where we are checking if an already-mapped SP is needed.
@@ -1231,17 +1251,18 @@ void IRLinker::findNeededSubprograms() {
   if (!IsMetadataLinkingPostpass)
     return;
   // In the case of metadata linking as a postpass (e.g. for function
-  // importing), see which DISubprogram MD from the source has an associated
-  // temporary metadata node, which means the SP was needed by an imported
-  // function.
+  // importing), see which MD from the source has an associated
+  // temporary metadata node, which means that any DISubprogram
+  // reached from that MD was needed by an imported function.
+  SmallPtrSet<const MDNode *, 16> Visited;
   for (auto MDI : MetadataToIDs) {
     const MDNode *Node = dyn_cast<MDNode>(MDI.first);
     if (!Node)
       continue;
-    DISubprogram *SP = getDISubprogram(Node);
-    if (!SP || !ValIDToTempMDMap->count(MDI.second))
+    if (!ValIDToTempMDMap->count(MDI.second))
       continue;
-    UnneededSubprograms.erase(SP);
+    // Find any SP needed recursively from this needed Node.
+    findReachedSubprograms(Node, Visited);
   }
 }
 

Modified: llvm/trunk/test/Linker/thinlto_funcimport_debug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/thinlto_funcimport_debug.ll?rev=258728&r1=258727&r2=258728&view=diff
==============================================================================
--- llvm/trunk/test/Linker/thinlto_funcimport_debug.ll (original)
+++ llvm/trunk/test/Linker/thinlto_funcimport_debug.ll Mon Jan 25 16:04:56 2016
@@ -18,6 +18,8 @@
 
 ; CHECK: distinct !DISubprogram(name: "func1"
 ; CHECK-NOT: distinct !DISubprogram(name: "func2"
+; CHECK: distinct !DISubprogram(name: "func3"
+; CHECK: distinct !DISubprogram(name: "func4"
 
 
 ; ModuleID = 'dbg.o'
@@ -55,7 +57,7 @@ attributes #1 = { nounwind readnone }
 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 251407) (llvm/trunk 251401)", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)
 !1 = !DIFile(filename: "dbg.c", directory: ".")
 !2 = !{}
-!3 = !{!4, !11}
+!3 = !{!4, !11, !27, !30}
 !4 = distinct !DISubprogram(name: "func1", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, variables: !8)
 !5 = !DISubroutineType(types: !6)
 !6 = !{!7, !7}
@@ -72,9 +74,17 @@ attributes #1 = { nounwind readnone }
 !17 = !DIExpression()
 !18 = !DILocation(line: 1, column: 15, scope: !4)
 !19 = !DILocation(line: 2, column: 7, scope: !4)
-!20 = !DILocation(line: 3, column: 9, scope: !21)
-!21 = distinct !DILexicalBlock(scope: !4, file: !1, line: 3, column: 7)
+!20 = !DILocation(line: 3, column: 9, scope: !21, inlinedAt: !26)
+!21 = distinct !DILexicalBlock(scope: !27, file: !1, line: 3, column: 7)
 !22 = !DILocation(line: 3, column: 7, scope: !4)
 !23 = !DILocation(line: 5, column: 3, scope: !4)
 !24 = !DILocation(line: 8, column: 15, scope: !11)
 !25 = !DILocation(line: 9, column: 3, scope: !11)
+!26 = !DILocation(line: 9, column: 3, scope: !4)
+!27 = distinct !DISubprogram(name: "func3", scope: !1, file: !1, line: 8, type: !5, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, variables: !28)
+!28 = !{!29}
+!29 = !DILocalVariable(name: "n", arg: 1, scope: !30, file: !1, line: 8, type: !7)
+!30 = distinct !DISubprogram(name: "func4", scope: !1, file: !1, line: 8, type: !5, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, variables: !31)
+!31 = !{!32}
+!32 = !DILocalVariable(name: "n", arg: 1, scope: !30, file: !1, line: 8, type: !7)
+




More information about the llvm-commits mailing list