summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2016-01-25 22:04:56 +0000
committerTeresa Johnson <tejohnson@google.com>2016-01-25 22:04:56 +0000
commit71d12d2a4efd17a286f3050410433d6c8a2c6005 (patch)
tree9777695aa654575c2fdf6a5a54e0a4f3c69df0aa /llvm/lib
parent392443879dce3a2244a2529ee1c058f1777c6945 (diff)
downloadbcm5719-llvm-71d12d2a4efd17a286f3050410433d6c8a2c6005.tar.gz
bcm5719-llvm-71d12d2a4efd17a286f3050410433d6c8a2c6005.zip
[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. llvm-svn: 258728
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Linker/IRMover.cpp33
1 files changed, 27 insertions, 6 deletions
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index f30b623b523..6dbc183f782 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -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(GlobalValue &Dst, GlobalValue &Src) {
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);
}
}
OpenPOWER on IntegriCloud