Index: llvm/trunk/include/llvm/Linker/Linker.h =================================================================== --- llvm/trunk/include/llvm/Linker/Linker.h +++ llvm/trunk/include/llvm/Linker/Linker.h @@ -67,10 +67,6 @@ DenseMap *ValIDToTempMDMap); }; -/// Perform in-place global value handling on the given Module for -/// exported local functions renamed and promoted for ThinLTO. -bool renameModuleForThinLTO(Module &M, const FunctionInfoIndex *Index); - } // End llvm namespace #endif Index: llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h +++ llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h @@ -0,0 +1,106 @@ +//===- FunctionImportUtils.h - Importing support utilities -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the FunctionImportGlobalProcessing class which is used +// to perform the necessary global value handling for function importing. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H +#define LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H + +#include "llvm/ADT/SetVector.h" +#include "llvm/IR/FunctionInfo.h" + +namespace llvm { +class Module; + +/// Class to handle necessary GlobalValue changes required by ThinLTO +/// function importing, including linkage changes and any necessary renaming. +class FunctionImportGlobalProcessing { + /// 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 *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 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: + FunctionImportGlobalProcessing( + Module &M, const FunctionInfoIndex *Index, + DenseSet *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(); + + static bool + doImportAsDefinition(const GlobalValue *SGV, + DenseSet *FunctionsToImport); + + /// Access the promoted globals that are now exported and need to be linked. + SetVector &getNewExportedValues() { return NewExportedValues; } +}; + +/// Perform in-place global value handling on the given Module for +/// exported local functions renamed and promoted for ThinLTO. +bool renameModuleForThinLTO(Module &M, const FunctionInfoIndex *Index); + +} // End llvm namespace + +#endif Index: llvm/trunk/lib/Linker/LinkModules.cpp =================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp +++ llvm/trunk/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 *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 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 *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 &getNewExportedValues() { return NewExportedValues; } -}; -} - -/// Checks if we should import SGV as a definition, otherwise import as a -/// declaration. -static bool -doImportAsDefinitionImpl(const GlobalValue *SGV, - DenseSet *FunctionsToImport) { - auto *GA = dyn_cast(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(SGV) && !SGV->isDeclaration() && - !SGV->hasWeakAnyLinkage()) - return true; - // Only import the function requested for importing. - auto *SF = dyn_cast(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(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(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(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(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(&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. //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp +++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Transforms/Utils/FunctionImportUtils.h" #include Index: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt +++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt @@ -13,6 +13,7 @@ DemoteRegToStack.cpp Evaluator.cpp FlattenCFG.cpp + FunctionImportUtils.cpp GlobalStatus.cpp InlineFunction.cpp InstructionNamer.cpp Index: llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp +++ llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp @@ -0,0 +1,237 @@ +//===- lib/Transforms/Utils/FunctionImportUtils.cpp - Importing utilities -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the FunctionImportGlobalProcessing class, used +// to perform the necessary global value handling for function importing. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/FunctionImportUtils.h" +using namespace llvm; + +/// Checks if we should import SGV as a definition, otherwise import as a +/// declaration. +bool FunctionImportGlobalProcessing::doImportAsDefinition( + const GlobalValue *SGV, DenseSet *FunctionsToImport) { + auto *GA = dyn_cast(SGV); + if (GA) { + if (GA->hasWeakAnyLinkage()) + return false; + const GlobalObject *GO = GA->getBaseObject(); + if (!GO->hasLinkOnceODRLinkage()) + return false; + return FunctionImportGlobalProcessing::doImportAsDefinition( + GO, FunctionsToImport); + } + // Always import GlobalVariable definitions, except for the special + // case of WeakAny which are imported as ExternalWeak declarations + // (see comments in FunctionImportGlobalProcessing::getLinkage). The linkage + // changes described in FunctionImportGlobalProcessing::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(SGV) && !SGV->isDeclaration() && + !SGV->hasWeakAnyLinkage()) + return true; + // Only import the function requested for importing. + auto *SF = dyn_cast(SGV); + if (SF && FunctionsToImport->count(SF)) + return true; + // Otherwise no. + return false; +} + +bool FunctionImportGlobalProcessing::doImportAsDefinition( + const GlobalValue *SGV) { + if (!isPerformingImport()) + return false; + return FunctionImportGlobalProcessing::doImportAsDefinition( + SGV, FunctionsToImport); +} + +bool FunctionImportGlobalProcessing::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(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 FunctionImportGlobalProcessing::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 +FunctionImportGlobalProcessing::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(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(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(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"); +} + +void FunctionImportGlobalProcessing::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(&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 FunctionImportGlobalProcessing::processGlobalsForThinLTO() { + for (GlobalVariable &GV : M.globals()) + processGlobalForThinLTO(GV); + for (Function &SF : M) + processGlobalForThinLTO(SF); + for (GlobalAlias &GA : M.aliases()) + processGlobalForThinLTO(GA); +} + +bool FunctionImportGlobalProcessing::run() { + processGlobalsForThinLTO(); + return false; +} + +bool llvm::renameModuleForThinLTO(Module &M, const FunctionInfoIndex *Index) { + FunctionImportGlobalProcessing ThinLTOProcessing(M, Index); + return ThinLTOProcessing.run(); +}