[llvm] r320895 - [ThinLTO] Enable importing of aliases as copy of aliasee

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 15 16:18:12 PST 2017


Author: tejohnson
Date: Fri Dec 15 16:18:12 2017
New Revision: 320895

URL: http://llvm.org/viewvc/llvm-project?rev=320895&view=rev
Log:
[ThinLTO] Enable importing of aliases as copy of aliasee

Summary:
This implements a missing feature to allow importing of aliases, which
was previously disabled because alias cannot be available_externally.
We instead import an alias as a copy of its aliasee.

Some additional work was required in the IndexBitcodeWriter for the
distributed build case, to ensure that the aliasee has a value id
in the distributed index file (i.e. even when it is not being
imported directly).

This is a performance win in codes that have many aliases, e.g. C++
applications that have many constructor and destructor aliases.

Reviewers: pcc

Subscribers: mehdi_amini, inglorion, eraman, llvm-commits

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

Modified:
    llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h
    llvm/trunk/include/llvm/IR/Value.h
    llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/IR/Value.cpp
    llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp
    llvm/trunk/test/ThinLTO/X86/Inputs/distributed_import.ll
    llvm/trunk/test/ThinLTO/X86/Inputs/distributed_indexes.ll
    llvm/trunk/test/ThinLTO/X86/alias_import.ll
    llvm/trunk/test/ThinLTO/X86/distributed_import.ll
    llvm/trunk/test/ThinLTO/X86/distributed_indexes.ll
    llvm/trunk/test/ThinLTO/X86/funcimport.ll
    llvm/trunk/test/Transforms/FunctionImport/funcimport.ll

Modified: llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h (original)
+++ llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h Fri Dec 15 16:18:12 2017
@@ -246,6 +246,7 @@ public:
   /// If this is an alias summary, returns the summary of the aliased object (a
   /// global variable or function), otherwise returns itself.
   GlobalValueSummary *getBaseObject();
+  const GlobalValueSummary *getBaseObject() const;
 
   friend class ModuleSummaryIndex;
   friend void computeDeadSymbols(class ModuleSummaryIndex &,
@@ -255,10 +256,14 @@ public:
 /// \brief Alias summary information.
 class AliasSummary : public GlobalValueSummary {
   GlobalValueSummary *AliaseeSummary;
+  // AliaseeGUID is only set and accessed when we are building a combined index
+  // via the BitcodeReader.
+  GlobalValue::GUID AliaseeGUID;
 
 public:
   AliasSummary(GVFlags Flags)
-      : GlobalValueSummary(AliasKind, Flags, ArrayRef<ValueInfo>{}) {}
+      : GlobalValueSummary(AliasKind, Flags, ArrayRef<ValueInfo>{}),
+        AliaseeSummary(nullptr), AliaseeGUID(0) {}
 
   /// Check if this is an alias summary.
   static bool classof(const GlobalValueSummary *GVS) {
@@ -266,6 +271,7 @@ public:
   }
 
   void setAliasee(GlobalValueSummary *Aliasee) { AliaseeSummary = Aliasee; }
+  void setAliaseeGUID(GlobalValue::GUID GUID) { AliaseeGUID = GUID; }
 
   const GlobalValueSummary &getAliasee() const {
     assert(AliaseeSummary && "Unexpected missing aliasee summary");
@@ -276,8 +282,18 @@ public:
     return const_cast<GlobalValueSummary &>(
                          static_cast<const AliasSummary *>(this)->getAliasee());
   }
+  const GlobalValue::GUID &getAliaseeGUID() const {
+    assert(AliaseeGUID && "Unexpected missing aliasee GUID");
+    return AliaseeGUID;
+  }
 };
 
+const inline GlobalValueSummary *GlobalValueSummary::getBaseObject() const {
+  if (auto *AS = dyn_cast<AliasSummary>(this))
+    return &AS->getAliasee();
+  return this;
+}
+
 inline GlobalValueSummary *GlobalValueSummary::getBaseObject() {
   if (auto *AS = dyn_cast<AliasSummary>(this))
     return &AS->getAliasee();

Modified: llvm/trunk/include/llvm/IR/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.h?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Value.h (original)
+++ llvm/trunk/include/llvm/IR/Value.h Fri Dec 15 16:18:12 2017
@@ -330,6 +330,10 @@ public:
     return UseList == nullptr;
   }
 
+  bool materialized_use_empty() const {
+    return UseList == nullptr;
+  }
+
   using use_iterator = use_iterator_impl<Use>;
   using const_use_iterator = use_iterator_impl<const Use>;
 

Modified: llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h (original)
+++ llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h Fri Dec 15 16:18:12 2017
@@ -98,6 +98,15 @@ void ComputeCrossModuleImportForModule(
     StringRef ModulePath, const ModuleSummaryIndex &Index,
     FunctionImporter::ImportMapTy &ImportList);
 
+/// Mark all external summaries in \p Index for import into the given module.
+/// Used for distributed builds using a distributed index.
+///
+/// \p ImportList will be populated with a map that can be passed to
+/// FunctionImporter::importFunctions() above (see description there).
+void ComputeCrossModuleImportForModuleFromIndex(
+    StringRef ModulePath, const ModuleSummaryIndex &Index,
+    FunctionImporter::ImportMapTy &ImportList);
+
 /// Compute all the symbols that are "dead": i.e these that can't be reached
 /// in the graph from any of the given symbols listed in
 /// \p GUIDPreservedSymbols.

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Fri Dec 15 16:18:12 2017
@@ -5202,6 +5202,7 @@ Error ModuleSummaryIndexBitcodeReader::p
       if (!AliaseeInModule)
         return error("Alias expects aliasee summary to be parsed");
       AS->setAliasee(AliaseeInModule);
+      AS->setAliaseeGUID(AliaseeGUID);
 
       auto GUID = getValueInfoFromValueId(ValueID);
       AS->setOriginalName(GUID.second);
@@ -5288,9 +5289,8 @@ Error ModuleSummaryIndexBitcodeReader::p
           getValueInfoFromValueId(AliaseeValueId).first.getGUID();
       auto AliaseeInModule =
           TheIndex.findSummaryInModule(AliaseeGUID, AS->modulePath());
-      if (!AliaseeInModule)
-        return error("Alias expects aliasee summary to be parsed");
       AS->setAliasee(AliaseeInModule);
+      AS->setAliaseeGUID(AliaseeGUID);
 
       ValueInfo VI = getValueInfoFromValueId(ValueID).first;
       LastSeenGUID = VI.getGUID();

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Fri Dec 15 16:18:12 2017
@@ -413,7 +413,7 @@ public:
     // in writing out the call graph edges. Save the mapping from GUID
     // to the new global value id to use when writing those edges, which
     // are currently saved in the index in terms of GUID.
-    forEachSummary([&](GVInfo I) {
+    forEachSummary([&](GVInfo I, bool) {
       GUIDToValueIdMap[I.first] = ++GlobalValueId;
     });
   }
@@ -428,12 +428,18 @@ public:
   void forEachSummary(Functor Callback) {
     if (ModuleToSummariesForIndex) {
       for (auto &M : *ModuleToSummariesForIndex)
-        for (auto &Summary : M.second)
-          Callback(Summary);
+        for (auto &Summary : M.second) {
+          Callback(Summary, false);
+          // Ensure aliasee is handled, e.g. for assigning a valueId,
+          // even if we are not importing the aliasee directly (the
+          // imported alias will contain a copy of aliasee).
+          if (auto *AS = dyn_cast<AliasSummary>(Summary.getSecond()))
+            Callback({AS->getAliaseeGUID(), &AS->getAliasee()}, true);
+        }
     } else {
       for (auto &Summaries : Index)
         for (auto &Summary : Summaries.second.SummaryList)
-          Callback({Summaries.first, Summary.get()});
+          Callback({Summaries.first, Summary.get()}, false);
     }
   }
 
@@ -3604,7 +3610,7 @@ void IndexBitcodeWriter::writeCombinedGl
     NameVals.clear();
   };
 
-  forEachSummary([&](GVInfo I) {
+  forEachSummary([&](GVInfo I, bool IsAliasee) {
     GlobalValueSummary *S = I.second;
     assert(S);
 
@@ -3612,6 +3618,12 @@ void IndexBitcodeWriter::writeCombinedGl
     assert(ValueId);
     SummaryToValueIdMap[S] = *ValueId;
 
+    // If this is invoked for an aliasee, we want to record the above
+    // mapping, but then not emit a summary entry (if the aliasee is
+    // to be imported, we will invoke this separately with IsAliasee=false).
+    if (IsAliasee)
+      return;
+
     if (auto *AS = dyn_cast<AliasSummary>(S)) {
       // Will process aliases as a post-pass because the reader wants all
       // global to be loaded first.

Modified: llvm/trunk/lib/IR/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Value.cpp?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Value.cpp (original)
+++ llvm/trunk/lib/IR/Value.cpp Fri Dec 15 16:18:12 2017
@@ -409,7 +409,7 @@ void Value::doRAUW(Value *New, bool NoMe
   if (!NoMetadata && isUsedByMetadata())
     ValueAsMetadata::handleRAUW(this, New);
 
-  while (!use_empty()) {
+  while (!materialized_use_empty()) {
     Use &U = *UseList;
     // Must handle Constants specially, we cannot call replaceUsesOfWith on a
     // constant because they are uniqued.

Modified: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp Fri Dec 15 16:18:12 2017
@@ -22,6 +22,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/IR/AutoUpgrade.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalAlias.h"
 #include "llvm/IR/GlobalObject.h"
@@ -44,7 +45,9 @@
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/IPO/Internalize.h"
+#include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
 #include <cassert>
 #include <memory>
 #include <set>
@@ -118,6 +121,12 @@ static cl::opt<std::string>
     SummaryFile("summary-file",
                 cl::desc("The summary file to use for function importing."));
 
+/// Used when testing importing from distributed indexes via opt
+// -function-import.
+static cl::opt<bool>
+    ImportAllIndex("import-all-index",
+                   cl::desc("Import all external functions in index."));
+
 // Load lazily a module from \p FileName in \p Context.
 static std::unique_ptr<Module> loadFile(const std::string &FileName,
                                         LLVMContext &Context) {
@@ -172,13 +181,8 @@ selectCallee(const ModuleSummaryIndex &I
         if (GlobalValue::isInterposableLinkage(GVSummary->linkage()))
           // There is no point in importing these, we can't inline them
           return false;
-        if (isa<AliasSummary>(GVSummary))
-          // Aliases can't point to "available_externally".
-          // FIXME: we should import alias as available_externally *function*,
-          // the destination module does not need to know it is an alias.
-          return false;
 
-        auto *Summary = cast<FunctionSummary>(GVSummary);
+        auto *Summary = cast<FunctionSummary>(GVSummary->getBaseObject());
 
         // If this is a local function, make sure we import the copy
         // in the caller's module. The only time a local function can
@@ -275,9 +279,7 @@ static void computeImportForFunction(
     }
 
     // "Resolve" the summary
-    assert(!isa<AliasSummary>(CalleeSummary) &&
-           "Unexpected alias in import list");
-    const auto *ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
+    const auto *ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary->getBaseObject());
 
     assert(ResolvedCalleeSummary->instCount() <= NewThreshold &&
            "selectCallee() didn't honor the threshold");
@@ -432,6 +434,19 @@ void llvm::ComputeCrossModuleImport(
 #endif
 }
 
+#ifndef NDEBUG
+static void dumpImportListForModule(StringRef ModulePath,
+                                    FunctionImporter::ImportMapTy &ImportList) {
+  DEBUG(dbgs() << "* Module " << ModulePath << " imports from "
+               << ImportList.size() << " modules.\n");
+  for (auto &Src : ImportList) {
+    auto SrcModName = Src.first();
+    DEBUG(dbgs() << " - " << Src.second.size() << " functions imported from "
+                 << SrcModName << "\n");
+  }
+#endif
+}
+
 /// Compute all the imports for the given module in the Index.
 void llvm::ComputeCrossModuleImportForModule(
     StringRef ModulePath, const ModuleSummaryIndex &Index,
@@ -446,13 +461,34 @@ void llvm::ComputeCrossModuleImportForMo
   ComputeImportForModule(FunctionSummaryMap, Index, ImportList);
 
 #ifndef NDEBUG
-  DEBUG(dbgs() << "* Module " << ModulePath << " imports from "
-               << ImportList.size() << " modules.\n");
-  for (auto &Src : ImportList) {
-    auto SrcModName = Src.first();
-    DEBUG(dbgs() << " - " << Src.second.size() << " functions imported from "
-                 << SrcModName << "\n");
+  dumpImportListForModule(ModulePath, ImportList);
+#endif
+}
+
+// Mark all external summaries in Index for import into the given module.
+// Used for distributed builds using a distributed index.
+void llvm::ComputeCrossModuleImportForModuleFromIndex(
+    StringRef ModulePath, const ModuleSummaryIndex &Index,
+    FunctionImporter::ImportMapTy &ImportList) {
+  for (auto &GlobalList : Index) {
+    // Ignore entries for undefined references.
+    if (GlobalList.second.SummaryList.empty())
+      continue;
+
+    auto GUID = GlobalList.first;
+    assert(GlobalList.second.SummaryList.size() == 1 &&
+           "Expected individual combined index to have one summary per GUID");
+    auto &Summary = GlobalList.second.SummaryList[0];
+    // Skip the summaries for the importing module. These are included to
+    // e.g. record required linkage changes.
+    if (Summary->modulePath() == ModulePath)
+      continue;
+    // Doesn't matter what value we plug in to the map, just needs an entry
+    // to provoke importing by thinBackend.
+    ImportList[Summary->modulePath()][GUID] = 1;
   }
+#ifndef NDEBUG
+  dumpImportListForModule(ModulePath, ImportList);
 #endif
 }
 
@@ -692,6 +728,20 @@ void llvm::thinLTOInternalizeModule(Modu
   internalizeModule(TheModule, MustPreserveGV);
 }
 
+/// Make alias a clone of its aliasee.
+static Function *replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA) {
+  Function *Fn = cast<Function>(GA->getBaseObject());
+
+  ValueToValueMapTy VMap;
+  Function *NewFn = CloneFunction(Fn, VMap);
+  // Clone should use the original alias's linkage and name, and we ensure
+  // all uses of alias instead use the new clone (casted if necessary).
+  NewFn->setLinkage(GA->getLinkage());
+  GA->replaceAllUsesWith(ConstantExpr::getBitCast(NewFn, GA->getType()));
+  NewFn->takeName(GA);
+  return NewFn;
+}
+
 // Automatically import functions in Module \p DestModule based on the summaries
 // index.
 Expected<bool> FunctionImporter::importFunctions(
@@ -761,17 +811,36 @@ Expected<bool> FunctionImporter::importF
         GlobalsToImport.insert(&GV);
       }
     }
-#ifndef NDEBUG
     for (GlobalAlias &GA : SrcModule->aliases()) {
       if (!GA.hasName())
         continue;
       auto GUID = GA.getGUID();
-      assert(!ImportGUIDs.count(GUID) && "Unexpected alias in import list");
-      DEBUG(dbgs() << "Not importing alias " << GUID
+      auto Import = ImportGUIDs.count(GUID);
+      DEBUG(dbgs() << (Import ? "Is" : "Not") << " importing alias " << GUID
                    << " " << GA.getName() << " from "
                    << SrcModule->getSourceFileName() << "\n");
+      if (Import) {
+        if (Error Err = GA.materialize())
+          return std::move(Err);
+        // Import alias as a copy of its aliasee.
+        GlobalObject *Base = GA.getBaseObject();
+        if (Error Err = Base->materialize())
+          return std::move(Err);
+        auto *Fn = replaceAliasWithAliasee(SrcModule.get(), &GA);
+        DEBUG(dbgs() << "Is importing aliasee fn " << Base->getGUID()
+              << " " << Base->getName() << " from "
+              << SrcModule->getSourceFileName() << "\n");
+        if (EnableImportMetadata) {
+          // Add 'thinlto_src_module' metadata for statistics and debugging.
+          Fn->setMetadata(
+              "thinlto_src_module",
+              MDNode::get(DestModule.getContext(),
+                          {MDString::get(DestModule.getContext(),
+                                         SrcModule->getSourceFileName())}));
+        }
+        GlobalsToImport.insert(Fn);
+      }
     }
-#endif
 
     // Upgrade debug info after we're done materializing all the globals and we
     // have loaded all the required metadata!
@@ -817,8 +886,15 @@ static bool doImportingForModule(Module
 
   // First step is collecting the import list.
   FunctionImporter::ImportMapTy ImportList;
-  ComputeCrossModuleImportForModule(M.getModuleIdentifier(), *Index,
-                                    ImportList);
+  // If requested, simply import all functions in the index. This is used
+  // when testing distributed backend handling via the opt tool, when
+  // we have distributed indexes containing exactly the summaries to import.
+  if (ImportAllIndex)
+    ComputeCrossModuleImportForModuleFromIndex(M.getModuleIdentifier(), *Index,
+                                               ImportList);
+  else
+    ComputeCrossModuleImportForModule(M.getModuleIdentifier(), *Index,
+                                      ImportList);
 
   // Conservatively mark all internal values as promoted. This interface is
   // only used when doing importing via the function importing pass. The pass

Modified: llvm/trunk/test/ThinLTO/X86/Inputs/distributed_import.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/distributed_import.ll?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/Inputs/distributed_import.ll (original)
+++ llvm/trunk/test/ThinLTO/X86/Inputs/distributed_import.ll Fri Dec 15 16:18:12 2017
@@ -6,3 +6,9 @@ entry:
   %0 = load i32, i32* @G
   ret i32 %0
 }
+
+ at analias = alias void (...), bitcast (void ()* @aliasee to void (...)*)
+define void @aliasee() {
+entry:
+      ret void
+}

Modified: llvm/trunk/test/ThinLTO/X86/Inputs/distributed_indexes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/distributed_indexes.ll?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/Inputs/distributed_indexes.ll (original)
+++ llvm/trunk/test/ThinLTO/X86/Inputs/distributed_indexes.ll Fri Dec 15 16:18:12 2017
@@ -2,3 +2,9 @@ define void @g() {
 entry:
   ret void
 }
+
+ at analias = alias void (...), bitcast (void ()* @aliasee to void (...)*)
+define void @aliasee() {
+entry:
+  ret void
+}

Modified: llvm/trunk/test/ThinLTO/X86/alias_import.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/alias_import.ll?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/alias_import.ll (original)
+++ llvm/trunk/test/ThinLTO/X86/alias_import.ll Fri Dec 15 16:18:12 2017
@@ -4,9 +4,9 @@
 ; 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 they cannot be imported for
-; now. This could be implemented by importing the alias as an
-; available_externally definition copied from the aliasee's body.
+; Alias can't point to "available_externally", so they are implemented by
+; importing the alias as an available_externally definition copied from the
+; aliasee's body.
 ; PROMOTE-DAG: @globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to void (...)*)
 ; PROMOTE-DAG: @globalfuncWeakAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
 ; PROMOTE-DAG: @globalfuncLinkonceAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
@@ -45,45 +45,43 @@
 ; PROMOTE-DAG: define weak void @linkoncefunc()
 ; PROMOTE-DAG: define weak void @weakfunc()
 
-; On the import side now, verify that aliases are not imported
-; IMPORT-DAG:  declare void @linkonceODRfuncWeakAlias
-; IMPORT-DAG:  declare void @linkonceODRfuncLinkonceAlias
-; IMPORT-DAG:  declare void @linkonceODRfuncAlias
-; IMPORT-DAG:  declare void @linkonceODRfuncWeakODRAlias
-; IMPORT-DAG:  declare void @linkonceODRfuncLinkonceODRAlias
-
-
-; On the import side, these aliases are not imported (they don't point to a linkonce_odr)
-; IMPORT-DAG: declare void @globalfuncAlias()
+; On the import side now, verify that aliases are imported unless they
+; are preemptible (non-ODR weak/linkonce).
+; IMPORT-DAG: declare void @linkonceODRfuncWeakAlias
+; IMPORT-DAG: declare void @linkonceODRfuncLinkonceAlias
+; IMPORT-DAG: define available_externally void @linkonceODRfuncAlias
+; IMPORT-DAG: define available_externally void @linkonceODRfuncWeakODRAlias
+; IMPORT-DAG: define available_externally void @linkonceODRfuncLinkonceODRAlias
+; IMPORT-DAG: define available_externally 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: define available_externally void @globalfuncWeakODRAlias()
+; IMPORT-DAG: define available_externally void @globalfuncLinkonceODRAlias()
+; IMPORT-DAG: define available_externally 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: define available_externally void @internalfuncWeakODRAlias()
+; IMPORT-DAG: define available_externally void @internalfuncLinkonceODRAlias()
+; IMPORT-DAG: define available_externally 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: define available_externally void @weakODRfuncWeakODRAlias()
+; IMPORT-DAG: define available_externally void @weakODRfuncLinkonceODRAlias()
+; IMPORT-DAG: define available_externally 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: define available_externally void @linkoncefuncWeakODRAlias()
+; IMPORT-DAG: define available_externally void @linkoncefuncLinkonceODRAlias()
+; IMPORT-DAG: define available_externally void @weakfuncAlias()
 ; IMPORT-DAG: declare void @weakfuncWeakAlias()
 ; IMPORT-DAG: declare void @weakfuncLinkonceAlias()
-; IMPORT-DAG: declare void @weakfuncWeakODRAlias()
-; IMPORT-DAG: declare void @weakfuncLinkonceODRAlias()
-; IMPORT-DAG: declare void @linkonceODRfuncAlias()
+; IMPORT-DAG: define available_externally void @weakfuncWeakODRAlias()
+; IMPORT-DAG: define available_externally void @weakfuncLinkonceODRAlias()
+; IMPORT-DAG: define available_externally void @linkonceODRfuncAlias()
 ; IMPORT-DAG: declare void @linkonceODRfuncWeakAlias()
-; IMPORT-DAG: declare void @linkonceODRfuncWeakODRAlias()
+; IMPORT-DAG: define available_externally void @linkonceODRfuncWeakODRAlias()
 ; IMPORT-DAG: declare void @linkonceODRfuncLinkonceAlias()
-; IMPORT-DAG: declare void @linkonceODRfuncLinkonceODRAlias()
+; IMPORT-DAG: define available_externally void @linkonceODRfuncLinkonceODRAlias()
 
 define i32 @main() #0 {
 entry:

Modified: llvm/trunk/test/ThinLTO/X86/distributed_import.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/distributed_import.ll?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/distributed_import.ll (original)
+++ llvm/trunk/test/ThinLTO/X86/distributed_import.ll Fri Dec 15 16:18:12 2017
@@ -10,11 +10,15 @@
 ; RUN: llvm-lto2 run %t1.bc %t2.bc -o %t.o -save-temps \
 ; RUN:     -thinlto-distributed-indexes \
 ; RUN:     -r=%t1.bc,g, \
+; RUN:     -r=%t1.bc,analias, \
 ; RUN:     -r=%t1.bc,f,px \
-; RUN:     -r=%t2.bc,g,px
-; RUN: opt -function-import -summary-file %t1.bc.thinlto.bc %t1.bc -o %t1.out
-; RUN: opt -function-import -summary-file %t2.bc.thinlto.bc %t2.bc -o %t2.out
-; RUN: llvm-dis -o - %t2.out | FileCheck %s
+; RUN:     -r=%t2.bc,g,px \
+; RUN:     -r=%t2.bc,analias,px \
+; RUN:     -r=%t2.bc,aliasee,px
+; RUN: opt -function-import -import-all-index -summary-file %t1.bc.thinlto.bc %t1.bc -o %t1.out
+; RUN: opt -function-import -import-all-index -summary-file %t2.bc.thinlto.bc %t2.bc -o %t2.out
+; RUN: llvm-dis -o - %t1.out | FileCheck %s --check-prefix=IMPORT
+; RUN: llvm-dis -o - %t2.out | FileCheck %s --check-prefix=EXPORT
 
 ; Save the generated index files.
 ; RUN: cp %t1.bc.thinlto.bc %t1.bc.thinlto.bc.orig
@@ -34,26 +38,35 @@
 ; RUN: llvm-lto2 run %t1.bc %t2.bc -o %t.o -save-temps \
 ; RUN:     -thinlto-distributed-indexes \
 ; RUN:     -r=%t1.bc,g, \
+; RUN:     -r=%t1.bc,analias, \
 ; RUN:     -r=%t1.bc,f,px \
-; RUN:     -r=%t2.bc,g,px
+; RUN:     -r=%t2.bc,g,px \
+; RUN:     -r=%t2.bc,analias,px \
+; RUN:     -r=%t2.bc,aliasee,px
 ; RUN: diff %t1.bc.thinlto.bc.orig %t1.bc.thinlto.bc
 ; RUN: diff %t2.bc.thinlto.bc.orig %t2.bc.thinlto.bc
 
 ; Make sure importing occurs as expected
 ; RUN: cp %t1.bc.sv %t1.bc
 ; RUN: cp %t2.bc.sv %t2.bc
-; RUN: opt -function-import -summary-file %t2.bc.thinlto.bc %t2.bc -o %t2.out
-; RUN: llvm-dis -o - %t2.out | FileCheck %s
-
-; CHECK: @G.llvm.
+; RUN: opt -function-import -import-all-index -summary-file %t1.bc.thinlto.bc %t1.bc -o %t1.out
+; RUN: opt -function-import -import-all-index -summary-file %t2.bc.thinlto.bc %t2.bc -o %t2.out
+; RUN: llvm-dis -o - %t1.out | FileCheck %s --check-prefix=IMPORT
+; RUN: llvm-dis -o - %t2.out | FileCheck %s --check-prefix=EXPORT
+
+; IMPORT: define available_externally i32 @g() !thinlto_src_module
+; IMPORT: define available_externally void @analias() !thinlto_src_module
+; EXPORT: @G.llvm.
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
 declare i32 @g(...)
+declare void @analias(...)
 
 define void @f() {
 entry:
   call i32 (...) @g()
+  call void (...) @analias()
   ret void
 }
 

Modified: llvm/trunk/test/ThinLTO/X86/distributed_indexes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/distributed_indexes.ll?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/distributed_indexes.ll (original)
+++ llvm/trunk/test/ThinLTO/X86/distributed_indexes.ll Fri Dec 15 16:18:12 2017
@@ -7,16 +7,22 @@
 
 ; The backend index for this module contains summaries from itself and
 ; Inputs/distributed_indexes.ll, as it imports from the latter.
+; We should import @g and alias @analias. While we don't import the aliasee
+; directly (and therefore don't have a third COMBINED record from module
+; id 1), we will have a VALUE_GUID for it (hence the 4 VALUE_GUID entries).
 ; BACKEND1: <MODULE_STRTAB_BLOCK
 ; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}distributed_indexes.ll.tmp{{.*}}.bc'
 ; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}distributed_indexes.ll.tmp{{.*}}.bc'
 ; BACKEND1-NEXT: </MODULE_STRTAB_BLOCK
 ; BACKEND1-NEXT: <GLOBALVAL_SUMMARY_BLOCK
 ; BACKEND1-NEXT: <VERSION
-; BACKEND1-NEXT: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-5300342847281564238}}
-; BACKEND1-NEXT: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-5300342847281564238}}
-; BACKEND1-NEXT: <COMBINED
-; BACKEND1-NEXT: <COMBINED
+; BACKEND1-DAG: <VALUE_GUID op0=2 op1=-5751648690987223394
+; BACKEND1-DAG: <VALUE_GUID op0=4 op1=-5300342847281564238
+; BACKEND1-DAG: <VALUE_GUID op0=1 op1=-3706093650706652785
+; BACKEND1-DAG: <VALUE_GUID op0=3 op1=-1039159065113703048
+; BACKEND1-DAG: <COMBINED {{.*}} op1=0
+; BACKEND1-DAG: <COMBINED {{.*}} op1=1
+; BACKEND1-DAG: <COMBINED_ALIAS {{.*}} op1=1
 ; BACKEND1-NEXT: </GLOBALVAL_SUMMARY_BLOCK
 
 ; The backend index for Input/distributed_indexes.ll contains summaries from
@@ -26,14 +32,20 @@
 ; BACKEND2-NEXT: </MODULE_STRTAB_BLOCK
 ; BACKEND2-NEXT: <GLOBALVAL_SUMMARY_BLOCK
 ; BACKEND2-NEXT: <VERSION
-; BACKEND2-NEXT: <VALUE_GUID op0=1 op1=-5300342847281564238
+; BACKEND2-DAG: <VALUE_GUID op0=1 op1=-5751648690987223394/>
+; BACKEND2-DAG: <VALUE_GUID op0=4 op1=-5300342847281564238/>
+; BACKEND2-DAG: <VALUE_GUID op0=3 op1=-1039159065113703048/>
 ; BACKEND2-NEXT: <COMBINED
+; BACKEND2-NEXT: <COMBINED
+; BACKEND2-NEXT: <COMBINED_ALIAS
 ; BACKEND2-NEXT: </GLOBALVAL_SUMMARY_BLOCK
 
 declare void @g(...)
+declare void @analias(...)
 
 define void @f() {
 entry:
   call void (...) @g()
+  call void (...) @analias()
   ret void
 }

Modified: llvm/trunk/test/ThinLTO/X86/funcimport.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/funcimport.ll?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/funcimport.ll (original)
+++ llvm/trunk/test/ThinLTO/X86/funcimport.ll Fri Dec 15 16:18:12 2017
@@ -16,17 +16,19 @@
 ; EXPORTSTATIC-DAG: define hidden i32 @staticfunc.llvm.0
 ; EXPORTSTATIC-DAG: define hidden void @staticfunc2.llvm.0
 
-; Ensure that both weak alias to an imported function and strong alias to a
-; non-imported function are correctly turned into declarations.
+; Ensure that weak alias to an imported function is correctly turned into
+; a declaration.
 ; Also ensures that alias to a linkonce function is turned into a declaration
 ; and that the associated linkonce function is not in the output, as it is
 ; lazily linked and never referenced/materialized.
 ; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t3.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORTGLOB1
 ; IMPORTGLOB1-DAG: define available_externally void @globalfunc1
 ; IMPORTGLOB1-DAG: declare void @weakalias
-; IMPORTGLOB1-DAG: declare void @analias
 ; IMPORTGLOB1-NOT: @linkoncealias
 ; IMPORTGLOB1-NOT: @linkoncefunc
+
+; A strong alias is imported as an available_externally copy of its aliasee.
+; IMPORTGLOB1-DAG: define available_externally void @analias
 ; IMPORTGLOB1-NOT: declare void @globalfunc2
 
 ; Verify that the optimizer run

Modified: llvm/trunk/test/Transforms/FunctionImport/funcimport.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionImport/funcimport.ll?rev=320895&r1=320894&r2=320895&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionImport/funcimport.ll (original)
+++ llvm/trunk/test/Transforms/FunctionImport/funcimport.ll Fri Dec 15 16:18:12 2017
@@ -36,13 +36,14 @@ entry:
 ; CHECK-DAG: declare void @weakalias
 declare void @weakalias(...) #1
 
-; Cannot create an alias to available_externally
-; CHECK-DAG: declare void @analias
+; External alias imported as available_externally copy of aliasee
+; CHECK-DAG: define available_externally void @analias
 declare void @analias(...) #1
 
-; Aliases are not imported
+; External alias imported as available_externally copy of aliasee
+; (linkoncealias is an external alias to a linkonce_odr)
 declare void @linkoncealias(...) #1
-; CHECK-DAG: declare void @linkoncealias(...)
+; CHECK-DAG: define available_externally void @linkoncealias()
 
 ; INSTLIMDEF-DAG: Import referencestatics
 ; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i) !thinlto_src_module !0 {
@@ -105,7 +106,7 @@ declare void @linkoncefunc2(...) #1
 declare void @variadic(...)
 
 ; INSTLIMDEF-DAG: Import globalfunc2
-; INSTLIMDEF-DAG: 11 function-import - Number of functions imported
+; INSTLIMDEF-DAG: 13 function-import - Number of functions imported
 ; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"}
 
 ; The actual GUID values will depend on path to test.




More information about the llvm-commits mailing list