[llvm] r266958 - ThinLTO: Resolve linkonce_odr aliases just like functions

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 20 22:47:17 PDT 2016


Author: mehdi_amini
Date: Thu Apr 21 00:47:17 2016
New Revision: 266958

URL: http://llvm.org/viewvc/llvm-project?rev=266958&view=rev
Log:
ThinLTO: Resolve linkonce_odr aliases just like functions

This help to streamline the process of handling importing since
we don't need to special case alias everywhere: just like
linkonce_odr function, make sure at least one alias is emitted
by turning it weak.

Differential Revision: http://reviews.llvm.org/D19308

From: Mehdi Amini <mehdi.amini at apple.com>

Added:
    llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll
    llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll
    llvm/trunk/test/ThinLTO/X86/alias_import.ll
    llvm/trunk/test/ThinLTO/X86/alias_resolution.ll
Modified:
    llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp
    llvm/trunk/test/ThinLTO/X86/odr_resolution.ll

Modified: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp?rev=266958&r1=266957&r2=266958&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp (original)
+++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp Thu Apr 21 00:47:17 2016
@@ -122,10 +122,11 @@ bool IsFirstDefinitionForLinker(const Gl
   return true;
 }
 
-static GlobalValue::LinkageTypes ResolveODR(const ModuleSummaryIndex &Index,
-                                            StringRef ModuleIdentifier,
-                                            GlobalValue::GUID GUID,
-                                            const GlobalValueSummary &GV) {
+static GlobalValue::LinkageTypes
+ResolveODR(const ModuleSummaryIndex &Index,
+           const FunctionImporter::ExportSetTy &ExportList,
+           StringRef ModuleIdentifier, GlobalValue::GUID GUID,
+           const GlobalValueSummary &GV) {
   auto HasMultipleCopies =
       [&](const GlobalValueInfoList &GVInfo) { return GVInfo.size() > 1; };
 
@@ -146,13 +147,19 @@ static GlobalValue::LinkageTypes Resolve
     auto &GVInfo = Index.findGlobalValueInfoList(GUID)->second;
     // We need to emit only one of these, the first module will keep
     // it, but turned into a weak while the others will drop it.
-    if (!HasMultipleCopies(GVInfo))
+    if (!HasMultipleCopies(GVInfo)) {
+      // Exported LinkonceODR needs to be promoted to not be discarded
+      if (GlobalValue::isDiscardableIfUnused(OriginalLinkage) &&
+          ExportList.count(GUID))
+        return GlobalValue::WeakODRLinkage;
       break;
+    }
     if (IsFirstDefinitionForLinker(GVInfo, Index, ModuleIdentifier))
       return GlobalValue::WeakODRLinkage;
-    else
-      return GlobalValue::AvailableExternallyLinkage;
-    break;
+    else if (isa<AliasSummary>(&GV))
+      // Alias can't be turned into available_externally.
+      return OriginalLinkage;
+    return GlobalValue::AvailableExternallyLinkage;
   }
   }
   return OriginalLinkage;
@@ -166,6 +173,7 @@ static GlobalValue::LinkageTypes Resolve
 /// one copy.
 static void ResolveODR(
     const ModuleSummaryIndex &Index,
+    const FunctionImporter::ExportSetTy &ExportList,
     const std::map<GlobalValue::GUID, GlobalValueSummary *> &DefinedGlobals,
     StringRef ModuleIdentifier,
     DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR) {
@@ -185,7 +193,8 @@ static void ResolveODR(
   for (auto &GV : DefinedGlobals) {
     if (GlobalInvolvedWithAlias.count(GV.second))
       continue;
-    auto NewLinkage = ResolveODR(Index, ModuleIdentifier, GV.first, *GV.second);
+    auto NewLinkage =
+        ResolveODR(Index, ExportList, ModuleIdentifier, GV.first, *GV.second);
     if (NewLinkage != GV.second->linkage()) {
       ResolvedODR[GV.first] = NewLinkage;
     }
@@ -213,6 +222,14 @@ void fixupODR(
                  << GV.getLinkage() << " to " << NewLinkage->second << "\n");
     GV.setLinkage(NewLinkage->second);
   }
+  for (auto &GV : TheModule.aliases()) {
+    auto NewLinkage = ResolvedODR.find(GV.getGUID());
+    if (NewLinkage == ResolvedODR.end())
+      continue;
+    DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() << "` from "
+                 << GV.getLinkage() << " to " << NewLinkage->second << "\n");
+    GV.setLinkage(NewLinkage->second);
+  }
 }
 
 static StringMap<MemoryBufferRef>
@@ -453,17 +470,25 @@ std::unique_ptr<ModuleSummaryIndex> Thin
  */
 void ThinLTOCodeGenerator::promote(Module &TheModule,
                                    ModuleSummaryIndex &Index) {
+  auto ModuleCount = Index.modulePaths().size();
   auto ModuleIdentifier = TheModule.getModuleIdentifier();
   // Collect for each module the list of function it defines (GUID -> Summary).
   StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
       ModuleToDefinedGVSummaries;
   Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
 
+  // Generate import/export list
+  StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount);
+  StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount);
+  ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists,
+                           ExportLists);
+  auto &ExportList = ExportLists[ModuleIdentifier];
+
   // Resolve the LinkOnceODR, trying to turn them into "available_externally"
   // where possible.
   // This is a compile-time optimization.
   DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> ResolvedODR;
-  ResolveODR(Index, ModuleToDefinedGVSummaries[ModuleIdentifier],
+  ResolveODR(Index, ExportList, ModuleToDefinedGVSummaries[ModuleIdentifier],
              ModuleIdentifier, ResolvedODR);
   fixupODR(TheModule, ResolvedODR);
 
@@ -577,9 +602,11 @@ void ThinLTOCodeGenerator::run() {
         Context.setDiscardValueNames(LTODiscardValueNames);
         Context.enableDebugTypeODRUniquing();
         auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier();
+        auto &ExportList = ExportLists[ModuleIdentifier];
 
         DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> ResolvedODR;
-        ResolveODR(*Index, ModuleToDefinedGVSummaries[ModuleIdentifier],
+        ResolveODR(*Index, ExportList,
+                   ModuleToDefinedGVSummaries[ModuleIdentifier],
                    ModuleIdentifier, ResolvedODR);
 
         // Parse module now

Added: llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll?rev=266958&view=auto
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll (added)
+++ llvm/trunk/test/ThinLTO/X86/Inputs/alias_import.ll Thu Apr 21 00:47:17 2016
@@ -0,0 +1,64 @@
+
+
+
+
+ at globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+ at globalfuncWeakAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+ at globalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+ at globalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+ at globalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+define void @globalfunc() {
+entry:
+  ret void
+}
+
+ at internalfuncAlias = alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+ at internalfuncWeakAlias = weak alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+ at internalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+ at internalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+ at internalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+define internal void @internalfunc() {
+entry:
+  ret void
+}
+
+ at linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+ at linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+ at linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+ at linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+ at linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+define linkonce_odr void @linkonceODRfunc() {
+entry:
+  ret void
+}
+
+ at weakODRfuncAlias = alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+ at weakODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+ at weakODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+ at weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+ at weakODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+define weak_odr void @weakODRfunc() {
+entry:
+  ret void
+}
+
+ at linkoncefuncAlias = alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+ at linkoncefuncWeakAlias = weak alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+ at linkoncefuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+ at linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+ at linkoncefuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+define linkonce void @linkoncefunc() {
+entry:
+  ret void
+}
+
+ at weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+ at weakfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+ at weakfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+ at weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+ at weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+define weak void @weakfunc() {
+entry:
+  ret void
+}
+

Added: llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll?rev=266958&view=auto
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll (added)
+++ llvm/trunk/test/ThinLTO/X86/Inputs/alias_resolution.ll Thu Apr 21 00:47:17 2016
@@ -0,0 +1,64 @@
+
+
+
+
+ at globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+ at globalfuncWeakAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+ at globalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+ at globalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+ at globalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+define void @globalfunc() {
+entry:
+  ret void
+}
+
+ at internalfuncAlias = alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+ at internalfuncWeakAlias = weak alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+ at internalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+ at internalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+ at internalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @internalfunc to void (...)*)
+define internal void @internalfunc() {
+entry:
+  ret void
+}
+
+ at linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+ at linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+ at linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+ at linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+ at linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+define linkonce_odr void @linkonceODRfunc() {
+entry:
+  ret void
+}
+
+ at weakODRfuncAlias = alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+ at weakODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+ at weakODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+ at weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+ at weakODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+define weak_odr void @weakODRfunc() {
+entry:
+  ret void
+}
+
+ at linkoncefuncAlias = alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+ at linkoncefuncWeakAlias = weak alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+ at linkoncefuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+ at linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+ at linkoncefuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+define linkonce void @linkoncefunc() {
+entry:
+  ret void
+}
+
+ at weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+ at weakfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+ at weakfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+ at weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+ at weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+define weak void @weakfunc() {
+entry:
+  ret void
+}
+

Added: llvm/trunk/test/ThinLTO/X86/alias_import.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/alias_import.ll?rev=266958&view=auto
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/alias_import.ll (added)
+++ llvm/trunk/test/ThinLTO/X86/alias_import.ll Thu Apr 21 00:47:17 2016
@@ -0,0 +1,168 @@
+; RUN: opt -module-summary %s -o %t1.bc
+; RUN: opt -module-summary %p/Inputs/alias_import.ll -o %t2.bc
+; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
+; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t2.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE
+; RUN: llvm-lto -thinlto-action=import -thinlto-index %t.index.bc %t1.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORT
+
+;
+; Alias can't point to "available_externally", so we can only import an alias
+; when we can import the aliasee with a linkage that won't be
+; available_externally, i.e linkOnceODR. (FIXME this limitation could be lifted)
+; PROMOTE-DAG: @globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+; PROMOTE-DAG: @globalfuncWeakAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+; PROMOTE-DAG: @globalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+; PROMOTE-DAG: @globalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+; PROMOTE-DAG: @globalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @globalfunc to void (...)*)
+; PROMOTE-DAG: @internalfuncAlias = alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*)
+; PROMOTE-DAG: @internalfuncWeakAlias = weak alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*)
+; PROMOTE-DAG: @internalfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*)
+; PROMOTE-DAG: @internalfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*)
+; PROMOTE-DAG: @internalfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*)
+; PROMOTE-DAG: @linkoncefuncAlias = alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+; PROMOTE-DAG: @linkoncefuncWeakAlias = weak alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+; PROMOTE-DAG: @linkoncefuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+; PROMOTE-DAG: @linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+; PROMOTE-DAG: @linkoncefuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+; PROMOTE-DAG: @weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+; PROMOTE-DAG: @weakfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+; PROMOTE-DAG: @weakfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+; PROMOTE-DAG: @weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+; PROMOTE-DAG: @weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+; PROMOTE-DAG: @weakODRfuncAlias = alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+; PROMOTE-DAG: @weakODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+; PROMOTE-DAG: @weakODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+; PROMOTE-DAG: @weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+; PROMOTE-DAG: @weakODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+
+; Only alias to LinkonceODR aliasee can be imported
+; PROMOTE-DAG: @linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; PROMOTE-DAG: @linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; PROMOTE-DAG: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; Amongst these that are imported, check that we promote only linkonce->weak
+; PROMOTE-DAG: @linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; PROMOTE-DAG: @linkonceODRfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+
+; These will be imported, check the linkage/renaming after promotion
+; PROMOTE-DAG: define void @globalfunc()
+; PROMOTE-DAG: define hidden void @internalfunc.llvm.0()
+; PROMOTE-DAG: define linkonce_odr void @linkonceODRfunc()
+; PROMOTE-DAG: define weak_odr void @weakODRfunc()
+; PROMOTE-DAG: define linkonce void @linkoncefunc()
+; PROMOTE-DAG: define weak void @weakfunc()
+
+; On the import side now, verify that aliases to a linkonce_odr are imported, but the weak (never import weak)
+; IMPORT-DAG:  declare void @linkonceODRfuncWeakAlias
+; IMPORT-DAG:  @linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; IMPORT-DAG:  @linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; IMPORT-DAG:  @linkonceODRfuncWeakODRAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; IMPORT-DAG:  @linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; IMPORT-DAG:  define linkonce_odr void @linkonceODRfunc()
+
+
+; On the import side, these aliases are not imported (they don't point to a linkonce_odr)
+; IMPORT-DAG: declare void @globalfuncAlias()
+; IMPORT-DAG: declare void @globalfuncWeakAlias()
+; IMPORT-DAG: declare void @globalfuncLinkonceAlias()
+; IMPORT-DAG: declare void @globalfuncWeakODRAlias()
+; IMPORT-DAG: declare void @globalfuncLinkonceODRAlias()
+; IMPORT-DAG: declare void @internalfuncAlias()
+; IMPORT-DAG: declare void @internalfuncWeakAlias()
+; IMPORT-DAG: declare void @internalfuncLinkonceAlias()
+; IMPORT-DAG: declare void @internalfuncWeakODRAlias()
+; IMPORT-DAG: declare void @internalfuncLinkonceODRAlias()
+; IMPORT-DAG: declare void @weakODRfuncAlias()
+; IMPORT-DAG: declare void @weakODRfuncWeakAlias()
+; IMPORT-DAG: declare void @weakODRfuncLinkonceAlias()
+; IMPORT-DAG: declare void @weakODRfuncWeakODRAlias()
+; IMPORT-DAG: declare void @weakODRfuncLinkonceODRAlias()
+; IMPORT-DAG: declare void @linkoncefuncAlias()
+; IMPORT-DAG: declare void @linkoncefuncWeakAlias()
+; IMPORT-DAG: declare void @linkoncefuncLinkonceAlias()
+; IMPORT-DAG: declare void @linkoncefuncWeakODRAlias()
+; IMPORT-DAG: declare void @linkoncefuncLinkonceODRAlias()
+; IMPORT-DAG: declare void @weakfuncAlias()
+; IMPORT-DAG: declare void @weakfuncWeakAlias()
+; IMPORT-DAG: declare void @weakfuncLinkonceAlias()
+; IMPORT-DAG: declare void @weakfuncWeakODRAlias()
+; IMPORT-DAG: declare void @weakfuncLinkonceODRAlias()
+
+
+
+define i32 @main() #0 {
+entry:
+  call void @globalfuncAlias()
+  call void @globalfuncWeakAlias()
+  call void @globalfuncLinkonceAlias()
+  call void @globalfuncWeakODRAlias()
+  call void @globalfuncLinkonceODRAlias()
+
+  call void @internalfuncAlias()
+  call void @internalfuncWeakAlias()
+  call void @internalfuncLinkonceAlias()
+  call void @internalfuncWeakODRAlias()
+  call void @internalfuncLinkonceODRAlias()
+  call void @linkonceODRfuncAlias()
+  call void @linkonceODRfuncWeakAlias()
+  call void @linkonceODRfuncLinkonceAlias()
+  call void @linkonceODRfuncWeakODRAlias()
+  call void @linkonceODRfuncLinkonceODRAlias()
+
+  call void @weakODRfuncAlias()
+  call void @weakODRfuncWeakAlias()
+  call void @weakODRfuncLinkonceAlias()
+  call void @weakODRfuncWeakODRAlias()
+  call void @weakODRfuncLinkonceODRAlias()
+
+  call void @linkoncefuncAlias()
+  call void @linkoncefuncWeakAlias()
+  call void @linkoncefuncLinkonceAlias()
+  call void @linkoncefuncWeakODRAlias()
+  call void @linkoncefuncLinkonceODRAlias()
+
+  call void @weakfuncAlias()
+  call void @weakfuncWeakAlias()
+  call void @weakfuncLinkonceAlias()
+  call void @weakfuncWeakODRAlias()
+  call void @weakfuncLinkonceODRAlias()
+
+  ret i32 0
+}
+
+
+declare void @globalfuncAlias()
+declare void @globalfuncWeakAlias()
+declare void @globalfuncLinkonceAlias()
+declare void @globalfuncWeakODRAlias()
+declare void @globalfuncLinkonceODRAlias()
+
+declare void @internalfuncAlias()
+declare void @internalfuncWeakAlias()
+declare void @internalfuncLinkonceAlias()
+declare void @internalfuncWeakODRAlias()
+declare void @internalfuncLinkonceODRAlias()
+
+declare void @linkonceODRfuncAlias()
+declare void @linkonceODRfuncWeakAlias()
+declare void @linkonceODRfuncLinkonceAlias()
+declare void @linkonceODRfuncWeakODRAlias()
+declare void @linkonceODRfuncLinkonceODRAlias()
+
+declare void @weakODRfuncAlias()
+declare void @weakODRfuncWeakAlias()
+declare void @weakODRfuncLinkonceAlias()
+declare void @weakODRfuncWeakODRAlias()
+declare void @weakODRfuncLinkonceODRAlias()
+
+declare void @linkoncefuncAlias()
+declare void @linkoncefuncWeakAlias()
+declare void @linkoncefuncLinkonceAlias()
+declare void @linkoncefuncWeakODRAlias()
+declare void @linkoncefuncLinkonceODRAlias()
+
+declare void @weakfuncAlias()
+declare void @weakfuncWeakAlias()
+declare void @weakfuncLinkonceAlias()
+declare void @weakfuncWeakODRAlias()
+declare void @weakfuncLinkonceODRAlias()
+
+

Added: llvm/trunk/test/ThinLTO/X86/alias_resolution.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/alias_resolution.ll?rev=266958&view=auto
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/alias_resolution.ll (added)
+++ llvm/trunk/test/ThinLTO/X86/alias_resolution.ll Thu Apr 21 00:47:17 2016
@@ -0,0 +1,82 @@
+; RUN: opt -module-summary %s -o %t1.bc
+; RUN: opt -module-summary %p/Inputs/alias_resolution.ll -o %t2.bc
+; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
+; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t2.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE_MOD2 --check-prefix=NOTPROMOTED
+; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t1.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE  --check-prefix=NOTPROMOTED
+
+; There is no importing going on with this IR, but let's check the ODR resolution for compile time
+
+; NOTPROMOTED: @linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc{{.*}} to void (...)*)
+; NOTPROMOTED: @linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @linkonceODRfunc{{.*}} to void (...)*)
+; NOTPROMOTED: @linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkonceODRfunc{{.*}} to void (...)*)
+; PROMOTE_MOD1: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
+; PROMOTE_MOD2: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+; PROMOTE_MOD1: @linkonceODRfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
+; PROMOTE_MOD2: @linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*)
+
+; NOTPROMOTED: @weakODRfuncAlias = alias void (...), bitcast (void ()* @weakODRfunc{{.*}} to void (...)*)
+; NOTPROMOTED: @weakODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakODRfunc{{.*}} to void (...)*)
+; NOTPROMOTED: @weakODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakODRfunc{{.*}} to void (...)*)
+; PROMOTE_MOD1: @weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
+; PROMOTE_MOD2: @weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+; PROMOTE_MOD1: @weakODRfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
+; PROMOTE_MOD2: @weakODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakODRfunc to void (...)*)
+
+; NOTPROMOTED: @linkoncefuncAlias = alias void (...), bitcast (void ()* @linkoncefunc{{.*}} to void (...)*)
+; NOTPROMOTED: @linkoncefuncWeakAlias = weak alias void (...), bitcast (void ()* @linkoncefunc{{.*}} to void (...)*)
+; NOTPROMOTED: @linkoncefuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkoncefunc{{.*}} to void (...)*)
+; PROMOTE_MOD1: @linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
+; PROMOTE_MOD2: @linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+; PROMOTE_MOD1: @linkoncefuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
+; PROMOTE_MOD2: @linkoncefuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
+
+; NOTPROMOTED: @weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc{{.*}} to void (...)*)
+; NOTPROMOTED: @weakfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakfunc{{.*}} to void (...)*)
+; NOTPROMOTED: @weakfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakfunc{{.*}} to void (...)*)
+; FIXME: The "resolution" should turn one of these to linkonce_odr
+; PROMOTE_MOD1: @weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakfunc.mod1 to void (...)*)
+; PROMOTE_MOD2: @weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+; PROMOTE_MOD1: @weakfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @weakfunc.mod1 to void (...)*)
+; PROMOTE_MOD2: @weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
+
+
+ at linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
+ at linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
+ at linkonceODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
+ at linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
+ at linkonceODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
+define linkonce_odr void @linkonceODRfunc.mod1() {
+entry:
+  ret void
+}
+
+ at weakODRfuncAlias = alias void (...), bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
+ at weakODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
+ at weakODRfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
+ at weakODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
+ at weakODRfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakODRfunc.mod1 to void (...)*)
+define weak_odr void @weakODRfunc.mod1() {
+entry:
+  ret void
+}
+
+ at linkoncefuncAlias = alias void (...), bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
+ at linkoncefuncWeakAlias = weak alias void (...), bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
+ at linkoncefuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
+ at linkoncefuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
+ at linkoncefuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @linkoncefunc.mod1 to void (...)*)
+define linkonce void @linkoncefunc.mod1() {
+entry:
+  ret void
+}
+
+ at weakfuncAlias = alias void (...), bitcast (void ()* @weakfunc.mod1 to void (...)*)
+ at weakfuncWeakAlias = weak alias void (...), bitcast (void ()* @weakfunc.mod1 to void (...)*)
+ at weakfuncLinkonceAlias = linkonce alias void (...), bitcast (void ()* @weakfunc.mod1 to void (...)*)
+ at weakfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @weakfunc.mod1 to void (...)*)
+ at weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakfunc.mod1 to void (...)*)
+define weak void @weakfunc.mod1() {
+entry:
+  ret void
+}
+

Modified: llvm/trunk/test/ThinLTO/X86/odr_resolution.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/odr_resolution.ll?rev=266958&r1=266957&r2=266958&view=diff
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/odr_resolution.ll (original)
+++ llvm/trunk/test/ThinLTO/X86/odr_resolution.ll Thu Apr 21 00:47:17 2016
@@ -10,8 +10,8 @@
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-apple-macosx10.11.0"
 
-; Alias are not optimized
-; MOD1: @linkoncealias = linkonce_odr alias void (), void ()* @linkonceodrfuncwithalias
+; Alias are resolved, but can't be turned into "available_externally"
+; MOD1: @linkoncealias = weak_odr alias void (), void ()* @linkonceodrfuncwithalias
 ; MOD2: @linkoncealias = linkonce_odr alias void (), void ()* @linkonceodrfuncwithalias
 @linkoncealias = linkonce_odr alias void (), void ()* @linkonceodrfuncwithalias
 




More information about the llvm-commits mailing list