summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Linker/LinkModules.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Linker/LinkModules.cpp')
-rw-r--r--contrib/llvm/lib/Linker/LinkModules.cpp908
1 files changed, 908 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Linker/LinkModules.cpp b/contrib/llvm/lib/Linker/LinkModules.cpp
new file mode 100644
index 0000000..6ffa71e
--- /dev/null
+++ b/contrib/llvm/lib/Linker/LinkModules.cpp
@@ -0,0 +1,908 @@
+//===- lib/Linker/LinkModules.cpp - Module Linker Implementation ----------===//
+//
+// 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 LLVM module linker.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+using namespace llvm;
+
+namespace {
+
+/// This is an implementation class for the LinkModules function, which is the
+/// entrypoint for this file.
+class ModuleLinker {
+ IRMover &Mover;
+ Module &SrcM;
+
+ SetVector<GlobalValue *> ValuesToLink;
+ StringSet<> Internalize;
+
+ /// For symbol clashes, prefer those from Src.
+ unsigned Flags;
+
+ /// Function index passed into ModuleLinker for using in function
+ /// importing/exporting handling.
+ const FunctionInfoIndex *ImportIndex;
+
+ /// Functions to import from source module, all other functions are
+ /// 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;
+
+ /// Association between metadata value id and temporary metadata that
+ /// remains unmapped after function importing. Saved during function
+ /// importing and consumed during the metadata linking postpass.
+ DenseMap<unsigned, MDNode *> *ValIDToTempMDMap;
+
+ /// Used as the callback for lazy linking.
+ /// The mover has just hit GV and we have to decide if it, and other members
+ /// of the same comdat, should be linked. Every member to be linked is passed
+ /// to Add.
+ void addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add);
+
+ bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; }
+ bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; }
+ bool shouldInternalizeLinkedSymbols() {
+ return Flags & Linker::InternalizeLinkedSymbols;
+ }
+
+ bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest,
+ const GlobalValue &Src);
+
+ /// Should we have mover and linker error diag info?
+ bool emitError(const Twine &Message) {
+ SrcM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message));
+ return true;
+ }
+
+ bool getComdatLeader(Module &M, StringRef ComdatName,
+ const GlobalVariable *&GVar);
+ bool computeResultingSelectionKind(StringRef ComdatName,
+ Comdat::SelectionKind Src,
+ Comdat::SelectionKind Dst,
+ Comdat::SelectionKind &Result,
+ bool &LinkFromSrc);
+ std::map<const Comdat *, std::pair<Comdat::SelectionKind, bool>>
+ ComdatsChosen;
+ bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK,
+ bool &LinkFromSrc);
+ // Keep track of the global value members of each comdat in source.
+ DenseMap<const Comdat *, std::vector<GlobalValue *>> ComdatMembers;
+
+ /// Given a global in the source module, return the global in the
+ /// destination module that is being linked to, if any.
+ GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) {
+ Module &DstM = Mover.getModule();
+ // If the source has no name it can't link. If it has local linkage,
+ // there is no name match-up going on.
+ if (!SrcGV->hasName() || GlobalValue::isLocalLinkage(SrcGV->getLinkage()))
+ return nullptr;
+
+ // Otherwise see if we have a match in the destination module's symtab.
+ GlobalValue *DGV = DstM.getNamedValue(SrcGV->getName());
+ if (!DGV)
+ return nullptr;
+
+ // If we found a global with the same name in the dest module, but it has
+ // internal linkage, we are really not doing any linkage here.
+ if (DGV->hasLocalLinkage())
+ return nullptr;
+
+ // Otherwise, we do in fact link to the destination global.
+ return DGV;
+ }
+
+ bool linkIfNeeded(GlobalValue &GV);
+
+ /// Helper method to check if we are importing from the current source
+ /// module.
+ bool isPerformingImport() const { return FunctionsToImport != nullptr; }
+
+ /// 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);
+
+public:
+ ModuleLinker(IRMover &Mover, Module &SrcM, unsigned Flags,
+ const FunctionInfoIndex *Index = nullptr,
+ DenseSet<const GlobalValue *> *FunctionsToImport = nullptr,
+ DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr)
+ : Mover(Mover), SrcM(SrcM), Flags(Flags), ImportIndex(Index),
+ FunctionsToImport(FunctionsToImport),
+ ValIDToTempMDMap(ValIDToTempMDMap) {
+ assert((ImportIndex || !FunctionsToImport) &&
+ "Expect a FunctionInfoIndex when importing");
+ // 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 (ImportIndex && !FunctionsToImport)
+ HasExportedFunctions = ImportIndex->hasExportedFunctions(SrcM);
+ assert((ValIDToTempMDMap || !FunctionsToImport) &&
+ "Function importing must provide a ValIDToTempMDMap");
+ }
+
+ 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");
+}
+
+static GlobalValue::VisibilityTypes
+getMinVisibility(GlobalValue::VisibilityTypes A,
+ GlobalValue::VisibilityTypes B) {
+ if (A == GlobalValue::HiddenVisibility || B == GlobalValue::HiddenVisibility)
+ return GlobalValue::HiddenVisibility;
+ if (A == GlobalValue::ProtectedVisibility ||
+ B == GlobalValue::ProtectedVisibility)
+ return GlobalValue::ProtectedVisibility;
+ return GlobalValue::DefaultVisibility;
+}
+
+bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName,
+ const GlobalVariable *&GVar) {
+ const GlobalValue *GVal = M.getNamedValue(ComdatName);
+ if (const auto *GA = dyn_cast_or_null<GlobalAlias>(GVal)) {
+ GVal = GA->getBaseObject();
+ if (!GVal)
+ // We cannot resolve the size of the aliasee yet.
+ return emitError("Linking COMDATs named '" + ComdatName +
+ "': COMDAT key involves incomputable alias size.");
+ }
+
+ GVar = dyn_cast_or_null<GlobalVariable>(GVal);
+ if (!GVar)
+ return emitError(
+ "Linking COMDATs named '" + ComdatName +
+ "': GlobalVariable required for data dependent selection!");
+
+ return false;
+}
+
+bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName,
+ Comdat::SelectionKind Src,
+ Comdat::SelectionKind Dst,
+ Comdat::SelectionKind &Result,
+ bool &LinkFromSrc) {
+ Module &DstM = Mover.getModule();
+ // The ability to mix Comdat::SelectionKind::Any with
+ // Comdat::SelectionKind::Largest is a behavior that comes from COFF.
+ bool DstAnyOrLargest = Dst == Comdat::SelectionKind::Any ||
+ Dst == Comdat::SelectionKind::Largest;
+ bool SrcAnyOrLargest = Src == Comdat::SelectionKind::Any ||
+ Src == Comdat::SelectionKind::Largest;
+ if (DstAnyOrLargest && SrcAnyOrLargest) {
+ if (Dst == Comdat::SelectionKind::Largest ||
+ Src == Comdat::SelectionKind::Largest)
+ Result = Comdat::SelectionKind::Largest;
+ else
+ Result = Comdat::SelectionKind::Any;
+ } else if (Src == Dst) {
+ Result = Dst;
+ } else {
+ return emitError("Linking COMDATs named '" + ComdatName +
+ "': invalid selection kinds!");
+ }
+
+ switch (Result) {
+ case Comdat::SelectionKind::Any:
+ // Go with Dst.
+ LinkFromSrc = false;
+ break;
+ case Comdat::SelectionKind::NoDuplicates:
+ return emitError("Linking COMDATs named '" + ComdatName +
+ "': noduplicates has been violated!");
+ case Comdat::SelectionKind::ExactMatch:
+ case Comdat::SelectionKind::Largest:
+ case Comdat::SelectionKind::SameSize: {
+ const GlobalVariable *DstGV;
+ const GlobalVariable *SrcGV;
+ if (getComdatLeader(DstM, ComdatName, DstGV) ||
+ getComdatLeader(SrcM, ComdatName, SrcGV))
+ return true;
+
+ const DataLayout &DstDL = DstM.getDataLayout();
+ const DataLayout &SrcDL = SrcM.getDataLayout();
+ uint64_t DstSize =
+ DstDL.getTypeAllocSize(DstGV->getType()->getPointerElementType());
+ uint64_t SrcSize =
+ SrcDL.getTypeAllocSize(SrcGV->getType()->getPointerElementType());
+ if (Result == Comdat::SelectionKind::ExactMatch) {
+ if (SrcGV->getInitializer() != DstGV->getInitializer())
+ return emitError("Linking COMDATs named '" + ComdatName +
+ "': ExactMatch violated!");
+ LinkFromSrc = false;
+ } else if (Result == Comdat::SelectionKind::Largest) {
+ LinkFromSrc = SrcSize > DstSize;
+ } else if (Result == Comdat::SelectionKind::SameSize) {
+ if (SrcSize != DstSize)
+ return emitError("Linking COMDATs named '" + ComdatName +
+ "': SameSize violated!");
+ LinkFromSrc = false;
+ } else {
+ llvm_unreachable("unknown selection kind");
+ }
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool ModuleLinker::getComdatResult(const Comdat *SrcC,
+ Comdat::SelectionKind &Result,
+ bool &LinkFromSrc) {
+ Module &DstM = Mover.getModule();
+ Comdat::SelectionKind SSK = SrcC->getSelectionKind();
+ StringRef ComdatName = SrcC->getName();
+ Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable();
+ Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(ComdatName);
+
+ if (DstCI == ComdatSymTab.end()) {
+ // Use the comdat if it is only available in one of the modules.
+ LinkFromSrc = true;
+ Result = SSK;
+ return false;
+ }
+
+ const Comdat *DstC = &DstCI->second;
+ Comdat::SelectionKind DSK = DstC->getSelectionKind();
+ return computeResultingSelectionKind(ComdatName, SSK, DSK, Result,
+ LinkFromSrc);
+}
+
+bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
+ const GlobalValue &Dest,
+ const GlobalValue &Src) {
+
+ // Should we unconditionally use the Src?
+ if (shouldOverrideFromSrc()) {
+ LinkFromSrc = true;
+ return false;
+ }
+
+ // We always have to add Src if it has appending linkage.
+ if (Src.hasAppendingLinkage()) {
+ // Should have prevented importing for appending linkage in linkIfNeeded.
+ assert(!isPerformingImport());
+ LinkFromSrc = true;
+ return false;
+ }
+
+ bool SrcIsDeclaration = Src.isDeclarationForLinker();
+ bool DestIsDeclaration = Dest.isDeclarationForLinker();
+
+ if (isPerformingImport()) {
+ if (isa<Function>(&Src)) {
+ // For functions, LinkFromSrc iff this is a function requested
+ // for importing. For variables, decide below normally.
+ LinkFromSrc = FunctionsToImport->count(&Src);
+ return false;
+ }
+
+ // Check if this is an alias with an already existing definition
+ // in Dest, which must have come from a prior importing pass from
+ // the same Src module. Unlike imported function and variable
+ // definitions, which are imported as available_externally and are
+ // not definitions for the linker, that is not a valid linkage for
+ // imported aliases which must be definitions. Simply use the existing
+ // Dest copy.
+ if (isa<GlobalAlias>(&Src) && !DestIsDeclaration) {
+ assert(isa<GlobalAlias>(&Dest));
+ LinkFromSrc = false;
+ return false;
+ }
+ }
+
+ if (SrcIsDeclaration) {
+ // If Src is external or if both Src & Dest are external.. Just link the
+ // external globals, we aren't adding anything.
+ if (Src.hasDLLImportStorageClass()) {
+ // If one of GVs is marked as DLLImport, result should be dllimport'ed.
+ LinkFromSrc = DestIsDeclaration;
+ return false;
+ }
+ // If the Dest is weak, use the source linkage.
+ if (Dest.hasExternalWeakLinkage()) {
+ LinkFromSrc = true;
+ return false;
+ }
+ // Link an available_externally over a declaration.
+ LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration();
+ return false;
+ }
+
+ if (DestIsDeclaration) {
+ // If Dest is external but Src is not:
+ LinkFromSrc = true;
+ return false;
+ }
+
+ if (Src.hasCommonLinkage()) {
+ if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) {
+ LinkFromSrc = true;
+ return false;
+ }
+
+ if (!Dest.hasCommonLinkage()) {
+ LinkFromSrc = false;
+ return false;
+ }
+
+ const DataLayout &DL = Dest.getParent()->getDataLayout();
+ uint64_t DestSize = DL.getTypeAllocSize(Dest.getType()->getElementType());
+ uint64_t SrcSize = DL.getTypeAllocSize(Src.getType()->getElementType());
+ LinkFromSrc = SrcSize > DestSize;
+ return false;
+ }
+
+ if (Src.isWeakForLinker()) {
+ assert(!Dest.hasExternalWeakLinkage());
+ assert(!Dest.hasAvailableExternallyLinkage());
+
+ if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) {
+ LinkFromSrc = true;
+ return false;
+ }
+
+ LinkFromSrc = false;
+ return false;
+ }
+
+ if (Dest.isWeakForLinker()) {
+ assert(Src.hasExternalLinkage());
+ LinkFromSrc = true;
+ return false;
+ }
+
+ assert(!Src.hasExternalWeakLinkage());
+ assert(!Dest.hasExternalWeakLinkage());
+ assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() &&
+ "Unexpected linkage type!");
+ return emitError("Linking globals named '" + Src.getName() +
+ "': symbol multiply defined!");
+}
+
+bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
+ GlobalValue *DGV = getLinkedToGlobal(&GV);
+
+ if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration()))
+ return false;
+
+ if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) {
+ auto *DGVar = dyn_cast<GlobalVariable>(DGV);
+ auto *SGVar = dyn_cast<GlobalVariable>(&GV);
+ if (DGVar && SGVar) {
+ if (DGVar->isDeclaration() && SGVar->isDeclaration() &&
+ (!DGVar->isConstant() || !SGVar->isConstant())) {
+ DGVar->setConstant(false);
+ SGVar->setConstant(false);
+ }
+ if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) {
+ unsigned Align = std::max(DGVar->getAlignment(), SGVar->getAlignment());
+ SGVar->setAlignment(Align);
+ DGVar->setAlignment(Align);
+ }
+ }
+
+ GlobalValue::VisibilityTypes Visibility =
+ getMinVisibility(DGV->getVisibility(), GV.getVisibility());
+ DGV->setVisibility(Visibility);
+ GV.setVisibility(Visibility);
+
+ bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr();
+ DGV->setUnnamedAddr(HasUnnamedAddr);
+ GV.setUnnamedAddr(HasUnnamedAddr);
+ }
+
+ // Don't want to append to global_ctors list, for example, when we
+ // are importing for ThinLTO, otherwise the global ctors and dtors
+ // get executed multiple times for local variables (the latter causing
+ // double frees).
+ if (GV.hasAppendingLinkage() && isPerformingImport())
+ return false;
+
+ if (isPerformingImport() && !doImportAsDefinition(&GV))
+ return false;
+
+ if (!DGV && !shouldOverrideFromSrc() &&
+ (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||
+ GV.hasAvailableExternallyLinkage()))
+ return false;
+
+ if (GV.isDeclaration())
+ return false;
+
+ if (const Comdat *SC = GV.getComdat()) {
+ bool LinkFromSrc;
+ Comdat::SelectionKind SK;
+ std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];
+ if (LinkFromSrc)
+ ValuesToLink.insert(&GV);
+ return false;
+ }
+
+ bool LinkFromSrc = true;
+ if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV))
+ return true;
+ if (LinkFromSrc)
+ ValuesToLink.insert(&GV);
+ return false;
+}
+
+void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) {
+ // Add these to the internalize list
+ if (!GV.hasLinkOnceLinkage())
+ return;
+
+ if (shouldInternalizeLinkedSymbols())
+ Internalize.insert(GV.getName());
+ Add(GV);
+
+ const Comdat *SC = GV.getComdat();
+ if (!SC)
+ return;
+ for (GlobalValue *GV2 : ComdatMembers[SC]) {
+ if (!GV2->hasLocalLinkage() && shouldInternalizeLinkedSymbols())
+ Internalize.insert(GV2->getName());
+ Add(*GV2);
+ }
+}
+
+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);
+ return;
+ }
+ GV.setLinkage(getLinkage(&GV));
+}
+
+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();
+ if (ComdatsChosen.count(&C))
+ continue;
+ Comdat::SelectionKind SK;
+ bool LinkFromSrc;
+ if (getComdatResult(&C, SK, LinkFromSrc))
+ return true;
+ ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc);
+ }
+
+ for (GlobalVariable &GV : SrcM.globals())
+ if (const Comdat *SC = GV.getComdat())
+ ComdatMembers[SC].push_back(&GV);
+
+ for (Function &SF : SrcM)
+ if (const Comdat *SC = SF.getComdat())
+ ComdatMembers[SC].push_back(&SF);
+
+ for (GlobalAlias &GA : SrcM.aliases())
+ if (const Comdat *SC = GA.getComdat())
+ ComdatMembers[SC].push_back(&GA);
+
+ // Insert all of the globals in src into the DstM module... without linking
+ // initializers (which could refer to functions not yet mapped over).
+ for (GlobalVariable &GV : SrcM.globals())
+ if (linkIfNeeded(GV))
+ return true;
+
+ for (Function &SF : SrcM)
+ if (linkIfNeeded(SF))
+ return true;
+
+ for (GlobalAlias &GA : SrcM.aliases())
+ if (linkIfNeeded(GA))
+ return true;
+
+ if (ImportIndex) {
+ ThinLTOGlobalProcessing ThinLTOProcessing(SrcM, ImportIndex,
+ FunctionsToImport);
+ if (ThinLTOProcessing.run())
+ return true;
+ for (auto *GV : ThinLTOProcessing.getNewExportedValues())
+ ValuesToLink.insert(GV);
+ }
+
+ for (unsigned I = 0; I < ValuesToLink.size(); ++I) {
+ GlobalValue *GV = ValuesToLink[I];
+ const Comdat *SC = GV->getComdat();
+ if (!SC)
+ continue;
+ for (GlobalValue *GV2 : ComdatMembers[SC])
+ ValuesToLink.insert(GV2);
+ }
+
+ if (shouldInternalizeLinkedSymbols()) {
+ for (GlobalValue *GV : ValuesToLink)
+ Internalize.insert(GV->getName());
+ }
+
+ if (Mover.move(SrcM, ValuesToLink.getArrayRef(),
+ [this](GlobalValue &GV, IRMover::ValueAdder Add) {
+ addLazyFor(GV, Add);
+ },
+ ValIDToTempMDMap, false))
+ return true;
+ Module &DstM = Mover.getModule();
+ for (auto &P : Internalize) {
+ GlobalValue *GV = DstM.getNamedValue(P.first());
+ GV->setLinkage(GlobalValue::InternalLinkage);
+ }
+
+ return false;
+}
+
+Linker::Linker(Module &M) : Mover(M) {}
+
+bool Linker::linkInModule(std::unique_ptr<Module> Src, unsigned Flags,
+ const FunctionInfoIndex *Index,
+ DenseSet<const GlobalValue *> *FunctionsToImport,
+ DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) {
+ ModuleLinker ModLinker(Mover, *Src, Flags, Index, FunctionsToImport,
+ ValIDToTempMDMap);
+ return ModLinker.run();
+}
+
+bool Linker::linkInModuleForCAPI(Module &Src) {
+ ModuleLinker ModLinker(Mover, Src, 0, nullptr, nullptr);
+ return ModLinker.run();
+}
+
+bool Linker::linkInMetadata(Module &Src,
+ DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) {
+ SetVector<GlobalValue *> ValuesToLink;
+ if (Mover.move(
+ Src, ValuesToLink.getArrayRef(),
+ [this](GlobalValue &GV, IRMover::ValueAdder Add) { assert(false); },
+ ValIDToTempMDMap, true))
+ return true;
+ return false;
+}
+
+//===----------------------------------------------------------------------===//
+// LinkModules entrypoint.
+//===----------------------------------------------------------------------===//
+
+/// This function links two modules together, with the resulting Dest module
+/// modified to be the composite of the two input modules. If an error occurs,
+/// true is returned and ErrorMsg (if not null) is set to indicate the problem.
+/// Upon failure, the Dest module could be in a modified state, and shouldn't be
+/// relied on to be consistent.
+bool Linker::linkModules(Module &Dest, std::unique_ptr<Module> Src,
+ unsigned Flags) {
+ Linker L(Dest);
+ return L.linkInModule(std::move(Src), Flags);
+}
+
+bool llvm::renameModuleForThinLTO(Module &M, const FunctionInfoIndex *Index) {
+ ThinLTOGlobalProcessing ThinLTOProcessing(M, Index);
+ return ThinLTOProcessing.run();
+}
+
+//===----------------------------------------------------------------------===//
+// C API.
+//===----------------------------------------------------------------------===//
+
+static void diagnosticHandler(const DiagnosticInfo &DI, void *C) {
+ auto *Message = reinterpret_cast<std::string *>(C);
+ raw_string_ostream Stream(*Message);
+ DiagnosticPrinterRawOStream DP(Stream);
+ DI.print(DP);
+}
+
+LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src,
+ LLVMLinkerMode Unused, char **OutMessages) {
+ Module *D = unwrap(Dest);
+ LLVMContext &Ctx = D->getContext();
+
+ LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
+ Ctx.getDiagnosticHandler();
+ void *OldDiagnosticContext = Ctx.getDiagnosticContext();
+ std::string Message;
+ Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
+
+ Linker L(*D);
+ Module *M = unwrap(Src);
+ LLVMBool Result = L.linkInModuleForCAPI(*M);
+
+ Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
+
+ if (OutMessages && Result)
+ *OutMessages = strdup(Message.c_str());
+ return Result;
+}
+
+LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) {
+ Module *D = unwrap(Dest);
+ std::unique_ptr<Module> M(unwrap(Src));
+ return Linker::linkModules(*D, std::move(M));
+}
OpenPOWER on IntegriCloud