[ThinLTO] Add an auto-hide feature

When a symbol is not exported outside of the
DSO, it is can be hidden. Usually we try to internalize
as much as possible, but it is not always possible, for
instance a symbol can be referenced outside of the LTO
unit, or there can be cross-module reference in ThinLTO.

This is a recommit of r293912 after fixing build failures,
and a recommit of r293918 after fixing LLD tests.

Differential Revision: https://reviews.llvm.org/D28978

llvm-svn: 293970
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 104fb19..b62db61 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -234,16 +234,16 @@
 
 // Convert the PreservedSymbols map from "Name" based to "GUID" based.
 static DenseSet<GlobalValue::GUID>
-computeGUIDPreservedSymbols(const StringSet<> &PreservedSymbols,
-                            const Triple &TheTriple) {
-  DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
-  for (auto &Entry : PreservedSymbols) {
+convertSymbolNamesToGUID(const StringSet<> &NamedSymbols,
+                         const Triple &TheTriple) {
+  DenseSet<GlobalValue::GUID> GUIDSymbols(NamedSymbols.size());
+  for (auto &Entry : NamedSymbols) {
     StringRef Name = Entry.first();
     if (TheTriple.isOSBinFormatMachO() && Name.size() > 0 && Name[0] == '_')
       Name = Name.drop_front();
-    GUIDPreservedSymbols.insert(GlobalValue::getGUID(Name));
+    GUIDSymbols.insert(GlobalValue::getGUID(Name));
   }
-  return GUIDPreservedSymbols;
+  return GUIDSymbols;
 }
 
 std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
@@ -554,10 +554,7 @@
 }
 
 void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) {
-  // FIXME: At the moment, we don't take advantage of this extra information,
-  // we're conservatively considering cross-references as preserved.
-  //  CrossReferencedSymbols.insert(Name);
-  PreservedSymbols.insert(Name);
+  CrossReferencedSymbols.insert(Name);
 }
 
 // TargetMachine factory
@@ -620,7 +617,7 @@
   Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
 
   // Convert the preserved symbols set from string to GUID
-  auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
+  auto GUIDPreservedSymbols = convertSymbolNamesToGUID(
       PreservedSymbols, Triple(TheModule.getTargetTriple()));
 
   // Compute "dead" symbols, we don't want to import/export these!
@@ -641,11 +638,13 @@
 
   // Promote the exported values in the index, so that they are promoted
   // in the module.
-  auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
+  auto isExported = [&](StringRef ModuleIdentifier,
+                        GlobalValue::GUID GUID) -> SummaryResolution {
     const auto &ExportList = ExportLists.find(ModuleIdentifier);
-    return (ExportList != ExportLists.end() &&
-            ExportList->second.count(GUID)) ||
-           GUIDPreservedSymbols.count(GUID);
+    if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) ||
+        GUIDPreservedSymbols.count(GUID))
+      return Exported;
+    return Internal;
   };
   thinLTOInternalizeAndPromoteInIndex(Index, isExported);
 
@@ -665,7 +664,7 @@
   Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
 
   // Convert the preserved symbols set from string to GUID
-  auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
+  auto GUIDPreservedSymbols = convertSymbolNamesToGUID(
       PreservedSymbols, Triple(TheModule.getTargetTriple()));
 
   // Compute "dead" symbols, we don't want to import/export these!
@@ -739,7 +738,7 @@
 
   // Convert the preserved symbols set from string to GUID
   auto GUIDPreservedSymbols =
-      computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
+      convertSymbolNamesToGUID(PreservedSymbols, TMBuilder.TheTriple);
 
   // Collect for each module the list of function it defines (GUID -> Summary).
   StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
@@ -761,11 +760,13 @@
     return;
 
   // Internalization
-  auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
+  auto isExported = [&](StringRef ModuleIdentifier,
+                        GlobalValue::GUID GUID) -> SummaryResolution {
     const auto &ExportList = ExportLists.find(ModuleIdentifier);
-    return (ExportList != ExportLists.end() &&
-            ExportList->second.count(GUID)) ||
-           GUIDPreservedSymbols.count(GUID);
+    if ((ExportList != ExportLists.end() && ExportList->second.count(GUID)) ||
+        GUIDPreservedSymbols.count(GUID))
+      return Exported;
+    return Internal;
   };
   thinLTOInternalizeAndPromoteInIndex(Index, isExported);
   thinLTOInternalizeModule(TheModule,
@@ -894,7 +895,9 @@
   // Convert the preserved symbols set from string to GUID, this is needed for
   // computing the caching hash and the internalization.
   auto GUIDPreservedSymbols =
-      computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
+      convertSymbolNamesToGUID(PreservedSymbols, TMBuilder.TheTriple);
+  auto GUIDCrossRefSymbols =
+      convertSymbolNamesToGUID(CrossReferencedSymbols, TMBuilder.TheTriple);
 
   // Compute "dead" symbols, we don't want to import/export these!
   auto DeadSymbols = computeDeadSymbols(*Index, GUIDPreservedSymbols);
@@ -916,11 +919,16 @@
   // impacts the caching.
   resolveWeakForLinkerInIndex(*Index, ResolvedODR);
 
-  auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
+  auto isExported = [&](StringRef ModuleIdentifier,
+                        GlobalValue::GUID GUID) -> SummaryResolution {
+    if (GUIDPreservedSymbols.count(GUID))
+      return Exported;
+    if (GUIDCrossRefSymbols.count(GUID))
+      return Hidden;
     const auto &ExportList = ExportLists.find(ModuleIdentifier);
-    return (ExportList != ExportLists.end() &&
-            ExportList->second.count(GUID)) ||
-           GUIDPreservedSymbols.count(GUID);
+    if (ExportList != ExportLists.end() && ExportList->second.count(GUID))
+      return Hidden;
+    return Internal;
   };
 
   // Use global summary-based analysis to identify symbols that can be