[ThinLTO] Move global processing from Linker to TransformUtils (NFC)

Summary:
As discussed on IRC, move the ThinLTOGlobalProcessing code out of
the linker, and into TransformUtils. The name of the class is changed
to FunctionImportGlobalProcessing.

Reviewers: joker.eph, rafael

Subscribers: joker.eph, llvm-commits

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

llvm-svn: 260395
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index 4bb4b3f..b96a6f4 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/lib/Linker/LinkModules.cpp
@@ -11,13 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Linker/Linker.h"
 #include "LinkDiagnosticInfo.h"
 #include "llvm-c/Linker.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/Linker/Linker.h"
+#include "llvm/Transforms/Utils/FunctionImportUtils.h"
 using namespace llvm;
 
 namespace {
@@ -141,257 +142,13 @@
 
   bool run();
 };
-
-/// Class to handle necessary GlobalValue changes required by ThinLTO including
-/// linkage changes and any necessary renaming.
-class ThinLTOGlobalProcessing {
-  /// The Module which we are exporting or importing functions from.
-  Module &M;
-
-  /// Function index passed in for function importing/exporting handling.
-  const FunctionInfoIndex *ImportIndex;
-
-  /// Functions to import from this module, all other functions will be
-  /// imported as declarations instead of definitions.
-  DenseSet<const GlobalValue *> *FunctionsToImport;
-
-  /// Set to true if the given FunctionInfoIndex contains any functions
-  /// from this source module, in which case we must conservatively assume
-  /// that any of its functions may be imported into another module
-  /// as part of a different backend compilation process.
-  bool HasExportedFunctions = false;
-
-  /// Populated during ThinLTO global processing with locals promoted
-  /// to global scope in an exporting module, which now need to be linked
-  /// in if calling from the ModuleLinker.
-  SetVector<GlobalValue *> NewExportedValues;
-
-  /// Check if we should promote the given local value to global scope.
-  bool doPromoteLocalToGlobal(const GlobalValue *SGV);
-
-  /// Helper methods to check if we are importing from or potentially
-  /// exporting from the current source module.
-  bool isPerformingImport() const { return FunctionsToImport != nullptr; }
-  bool isModuleExporting() const { return HasExportedFunctions; }
-
-  /// If we are importing from the source module, checks if we should
-  /// import SGV as a definition, otherwise import as a declaration.
-  bool doImportAsDefinition(const GlobalValue *SGV);
-
-  /// Get the name for SGV that should be used in the linked destination
-  /// module. Specifically, this handles the case where we need to rename
-  /// a local that is being promoted to global scope.
-  std::string getName(const GlobalValue *SGV);
-
-  /// Process globals so that they can be used in ThinLTO. This includes
-  /// promoting local variables so that they can be reference externally by
-  /// thin lto imported globals and converting strong external globals to
-  /// available_externally.
-  void processGlobalsForThinLTO();
-  void processGlobalForThinLTO(GlobalValue &GV);
-
-  /// Get the new linkage for SGV that should be used in the linked destination
-  /// module. Specifically, for ThinLTO importing or exporting it may need
-  /// to be adjusted.
-  GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV);
-
-public:
-  ThinLTOGlobalProcessing(
-      Module &M, const FunctionInfoIndex *Index,
-      DenseSet<const GlobalValue *> *FunctionsToImport = nullptr)
-      : M(M), ImportIndex(Index), FunctionsToImport(FunctionsToImport) {
-    // If we have a FunctionInfoIndex but no function to import,
-    // then this is the primary module being compiled in a ThinLTO
-    // backend compilation, and we need to see if it has functions that
-    // may be exported to another backend compilation.
-    if (!FunctionsToImport)
-      HasExportedFunctions = ImportIndex->hasExportedFunctions(M);
-  }
-
-  bool run();
-
-  /// Access the promoted globals that are now exported and need to be linked.
-  SetVector<GlobalValue *> &getNewExportedValues() { return NewExportedValues; }
-};
-}
-
-/// Checks if we should import SGV as a definition, otherwise import as a
-/// declaration.
-static bool
-doImportAsDefinitionImpl(const GlobalValue *SGV,
-                         DenseSet<const GlobalValue *> *FunctionsToImport) {
-  auto *GA = dyn_cast<GlobalAlias>(SGV);
-  if (GA) {
-    if (GA->hasWeakAnyLinkage())
-      return false;
-    const GlobalObject *GO = GA->getBaseObject();
-    if (!GO->hasLinkOnceODRLinkage())
-      return false;
-    return doImportAsDefinitionImpl(GO, FunctionsToImport);
-  }
-  // Always import GlobalVariable definitions, except for the special
-  // case of WeakAny which are imported as ExternalWeak declarations
-  // (see comments in ModuleLinker::getLinkage). The linkage changes
-  // described in ModuleLinker::getLinkage ensure the correct behavior (e.g.
-  // global variables with external linkage are transformed to
-  // available_externally definitions, which are ultimately turned into
-  // declarations after the EliminateAvailableExternally pass).
-  if (isa<GlobalVariable>(SGV) && !SGV->isDeclaration() &&
-      !SGV->hasWeakAnyLinkage())
-    return true;
-  // Only import the function requested for importing.
-  auto *SF = dyn_cast<Function>(SGV);
-  if (SF && FunctionsToImport->count(SF))
-    return true;
-  // Otherwise no.
-  return false;
-}
-
-bool ThinLTOGlobalProcessing::doImportAsDefinition(const GlobalValue *SGV) {
-  if (!isPerformingImport())
-    return false;
-  return doImportAsDefinitionImpl(SGV, FunctionsToImport);
 }
 
 bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) {
   if (!isPerformingImport())
     return false;
-  return doImportAsDefinitionImpl(SGV, FunctionsToImport);
-}
-
-bool ThinLTOGlobalProcessing::doPromoteLocalToGlobal(const GlobalValue *SGV) {
-  assert(SGV->hasLocalLinkage());
-  // Both the imported references and the original local variable must
-  // be promoted.
-  if (!isPerformingImport() && !isModuleExporting())
-    return false;
-
-  // Local const variables never need to be promoted unless they are address
-  // taken. The imported uses can simply use the clone created in this module.
-  // For now we are conservative in determining which variables are not
-  // address taken by checking the unnamed addr flag. To be more aggressive,
-  // the address taken information must be checked earlier during parsing
-  // of the module and recorded in the function index for use when importing
-  // from that module.
-  auto *GVar = dyn_cast<GlobalVariable>(SGV);
-  if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr())
-    return false;
-
-  // Eventually we only need to promote functions in the exporting module that
-  // are referenced by a potentially exported function (i.e. one that is in the
-  // function index).
-  return true;
-}
-
-std::string ThinLTOGlobalProcessing::getName(const GlobalValue *SGV) {
-  // For locals that must be promoted to global scope, ensure that
-  // the promoted name uniquely identifies the copy in the original module,
-  // using the ID assigned during combined index creation. When importing,
-  // we rename all locals (not just those that are promoted) in order to
-  // avoid naming conflicts between locals imported from different modules.
-  if (SGV->hasLocalLinkage() &&
-      (doPromoteLocalToGlobal(SGV) || isPerformingImport()))
-    return FunctionInfoIndex::getGlobalNameForLocal(
-        SGV->getName(),
-        ImportIndex->getModuleId(SGV->getParent()->getModuleIdentifier()));
-  return SGV->getName();
-}
-
-GlobalValue::LinkageTypes
-ThinLTOGlobalProcessing::getLinkage(const GlobalValue *SGV) {
-  // Any local variable that is referenced by an exported function needs
-  // to be promoted to global scope. Since we don't currently know which
-  // functions reference which local variables/functions, we must treat
-  // all as potentially exported if this module is exporting anything.
-  if (isModuleExporting()) {
-    if (SGV->hasLocalLinkage() && doPromoteLocalToGlobal(SGV))
-      return GlobalValue::ExternalLinkage;
-    return SGV->getLinkage();
-  }
-
-  // Otherwise, if we aren't importing, no linkage change is needed.
-  if (!isPerformingImport())
-    return SGV->getLinkage();
-
-  switch (SGV->getLinkage()) {
-  case GlobalValue::ExternalLinkage:
-    // External defnitions are converted to available_externally
-    // definitions upon import, so that they are available for inlining
-    // and/or optimization, but are turned into declarations later
-    // during the EliminateAvailableExternally pass.
-    if (doImportAsDefinition(SGV) && !dyn_cast<GlobalAlias>(SGV))
-      return GlobalValue::AvailableExternallyLinkage;
-    // An imported external declaration stays external.
-    return SGV->getLinkage();
-
-  case GlobalValue::AvailableExternallyLinkage:
-    // An imported available_externally definition converts
-    // to external if imported as a declaration.
-    if (!doImportAsDefinition(SGV))
-      return GlobalValue::ExternalLinkage;
-    // An imported available_externally declaration stays that way.
-    return SGV->getLinkage();
-
-  case GlobalValue::LinkOnceAnyLinkage:
-  case GlobalValue::LinkOnceODRLinkage:
-    // These both stay the same when importing the definition.
-    // The ThinLTO pass will eventually force-import their definitions.
-    return SGV->getLinkage();
-
-  case GlobalValue::WeakAnyLinkage:
-    // Can't import weak_any definitions correctly, or we might change the
-    // program semantics, since the linker will pick the first weak_any
-    // definition and importing would change the order they are seen by the
-    // linker. The module linking caller needs to enforce this.
-    assert(!doImportAsDefinition(SGV));
-    // If imported as a declaration, it becomes external_weak.
-    return GlobalValue::ExternalWeakLinkage;
-
-  case GlobalValue::WeakODRLinkage:
-    // For weak_odr linkage, there is a guarantee that all copies will be
-    // equivalent, so the issue described above for weak_any does not exist,
-    // and the definition can be imported. It can be treated similarly
-    // to an imported externally visible global value.
-    if (doImportAsDefinition(SGV) && !dyn_cast<GlobalAlias>(SGV))
-      return GlobalValue::AvailableExternallyLinkage;
-    else
-      return GlobalValue::ExternalLinkage;
-
-  case GlobalValue::AppendingLinkage:
-    // It would be incorrect to import an appending linkage variable,
-    // since it would cause global constructors/destructors to be
-    // executed multiple times. This should have already been handled
-    // by linkIfNeeded, and we will assert in shouldLinkFromSource
-    // if we try to import, so we simply return AppendingLinkage.
-    return GlobalValue::AppendingLinkage;
-
-  case GlobalValue::InternalLinkage:
-  case GlobalValue::PrivateLinkage:
-    // If we are promoting the local to global scope, it is handled
-    // similarly to a normal externally visible global.
-    if (doPromoteLocalToGlobal(SGV)) {
-      if (doImportAsDefinition(SGV) && !dyn_cast<GlobalAlias>(SGV))
-        return GlobalValue::AvailableExternallyLinkage;
-      else
-        return GlobalValue::ExternalLinkage;
-    }
-    // A non-promoted imported local definition stays local.
-    // The ThinLTO pass will eventually force-import their definitions.
-    return SGV->getLinkage();
-
-  case GlobalValue::ExternalWeakLinkage:
-    // External weak doesn't apply to definitions, must be a declaration.
-    assert(!doImportAsDefinition(SGV));
-    // Linkage stays external_weak.
-    return SGV->getLinkage();
-
-  case GlobalValue::CommonLinkage:
-    // Linkage stays common on definitions.
-    // The ThinLTO pass will eventually force-import their definitions.
-    return SGV->getLinkage();
-  }
-
-  llvm_unreachable("unknown linkage type");
+  return FunctionImportGlobalProcessing::doImportAsDefinition(
+      SGV, FunctionsToImport);
 }
 
 static GlobalValue::VisibilityTypes
@@ -713,46 +470,6 @@
   }
 }
 
-void ThinLTOGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
-  if (GV.hasLocalLinkage() &&
-      (doPromoteLocalToGlobal(&GV) || isPerformingImport())) {
-    GV.setName(getName(&GV));
-    GV.setLinkage(getLinkage(&GV));
-    if (!GV.hasLocalLinkage())
-      GV.setVisibility(GlobalValue::HiddenVisibility);
-    if (isModuleExporting())
-      NewExportedValues.insert(&GV);
-  } else
-    GV.setLinkage(getLinkage(&GV));
-
-  // Remove functions imported as available externally defs from comdats,
-  // as this is a declaration for the linker, and will be dropped eventually.
-  // It is illegal for comdats to contain declarations.
-  auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
-  if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
-    // The IRMover should not have placed any imported declarations in
-    // a comdat, so the only declaration that should be in a comdat
-    // at this point would be a definition imported as available_externally.
-    assert(GO->hasAvailableExternallyLinkage() &&
-           "Expected comdat on definition (possibly available external)");
-    GO->setComdat(nullptr);
-  }
-}
-
-void ThinLTOGlobalProcessing::processGlobalsForThinLTO() {
-  for (GlobalVariable &GV : M.globals())
-    processGlobalForThinLTO(GV);
-  for (Function &SF : M)
-    processGlobalForThinLTO(SF);
-  for (GlobalAlias &GA : M.aliases())
-    processGlobalForThinLTO(GA);
-}
-
-bool ThinLTOGlobalProcessing::run() {
-  processGlobalsForThinLTO();
-  return false;
-}
-
 bool ModuleLinker::run() {
   for (const auto &SMEC : SrcM.getComdatSymbolTable()) {
     const Comdat &C = SMEC.getValue();
@@ -792,8 +509,8 @@
       return true;
 
   if (ImportIndex) {
-    ThinLTOGlobalProcessing ThinLTOProcessing(SrcM, ImportIndex,
-                                              FunctionsToImport);
+    FunctionImportGlobalProcessing ThinLTOProcessing(SrcM, ImportIndex,
+                                                     FunctionsToImport);
     if (ThinLTOProcessing.run())
       return true;
     for (auto *GV : ThinLTOProcessing.getNewExportedValues())
@@ -871,11 +588,6 @@
   return L.linkInModule(std::move(Src), Flags);
 }
 
-bool llvm::renameModuleForThinLTO(Module &M, const FunctionInfoIndex *Index) {
-  ThinLTOGlobalProcessing ThinLTOProcessing(M, Index);
-  return ThinLTOProcessing.run();
-}
-
 //===----------------------------------------------------------------------===//
 // C API.
 //===----------------------------------------------------------------------===//