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.cpp607
1 files changed, 166 insertions, 441 deletions
diff --git a/contrib/llvm/lib/Linker/LinkModules.cpp b/contrib/llvm/lib/Linker/LinkModules.cpp
index 6ffa71e..fae9c95 100644
--- a/contrib/llvm/lib/Linker/LinkModules.cpp
+++ b/contrib/llvm/lib/Linker/LinkModules.cpp
@@ -11,13 +11,15 @@
//
//===----------------------------------------------------------------------===//
-#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/Support/Error.h"
+#include "llvm/Transforms/Utils/FunctionImportUtils.h"
using namespace llvm;
namespace {
@@ -26,7 +28,7 @@ namespace {
/// entrypoint for this file.
class ModuleLinker {
IRMover &Mover;
- Module &SrcM;
+ std::unique_ptr<Module> SrcM;
SetVector<GlobalValue *> ValuesToLink;
StringSet<> Internalize;
@@ -34,31 +36,19 @@ class ModuleLinker {
/// 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;
+ DenseSet<const GlobalValue *> *GlobalsToImport;
/// 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);
+ void addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add);
+ bool shouldLinkReferencedLinkOnce() {
+ return !(Flags & Linker::DontForceLinkLinkonceODR);
+ }
bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; }
bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; }
bool shouldInternalizeLinkedSymbols() {
@@ -70,7 +60,7 @@ class ModuleLinker {
/// Should we have mover and linker error diag info?
bool emitError(const Twine &Message) {
- SrcM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message));
+ SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message));
return true;
}
@@ -85,8 +75,8 @@ class ModuleLinker {
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;
+ // Keep track of the lazy linked global members of each comdat in source.
+ DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers;
/// Given a global in the source module, return the global in the
/// destination module that is being linked to, if any.
@@ -111,289 +101,36 @@ class ModuleLinker {
return DGV;
}
+ /// Drop GV if it is a member of a comdat that we are dropping.
+ /// This can happen with COFF's largest selection kind.
+ void dropReplacedComdat(GlobalValue &GV,
+ const DenseSet<const Comdat *> &ReplacedDstComdats);
+
bool linkIfNeeded(GlobalValue &GV);
/// Helper method to check if we are importing from the current source
/// module.
- bool isPerformingImport() const { return FunctionsToImport != nullptr; }
+ bool isPerformingImport() const { return GlobalsToImport != 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");
- }
+ ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags,
+ DenseSet<const GlobalValue *> *GlobalsToImport = nullptr)
+ : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags),
+ GlobalsToImport(GlobalsToImport) {}
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,
+ GlobalsToImport);
}
static GlobalValue::VisibilityTypes
@@ -466,15 +203,13 @@ bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName,
const GlobalVariable *DstGV;
const GlobalVariable *SrcGV;
if (getComdatLeader(DstM, ComdatName, DstGV) ||
- getComdatLeader(SrcM, ComdatName, SrcGV))
+ 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());
+ const DataLayout &SrcDL = SrcM->getDataLayout();
+ uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType());
+ uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType());
if (Result == Comdat::SelectionKind::ExactMatch) {
if (SrcGV->getInitializer() != DstGV->getInitializer())
return emitError("Linking COMDATs named '" + ComdatName +
@@ -537,31 +272,15 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
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;
- }
+ // LinkFromSrc iff this is a global requested for importing.
+ LinkFromSrc = GlobalsToImport->count(&Src);
+ return false;
}
+ bool SrcIsDeclaration = Src.isDeclarationForLinker();
+ bool DestIsDeclaration = Dest.isDeclarationForLinker();
+
if (SrcIsDeclaration) {
// If Src is external or if both Src & Dest are external.. Just link the
// external globals, we aren't adding anything.
@@ -598,8 +317,8 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
}
const DataLayout &DL = Dest.getParent()->getDataLayout();
- uint64_t DestSize = DL.getTypeAllocSize(Dest.getType()->getElementType());
- uint64_t SrcSize = DL.getTypeAllocSize(Src.getType()->getElementType());
+ uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType());
+ uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType());
LinkFromSrc = SrcSize > DestSize;
return false;
}
@@ -658,9 +377,10 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
DGV->setVisibility(Visibility);
GV.setVisibility(Visibility);
- bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr();
- DGV->setUnnamedAddr(HasUnnamedAddr);
- GV.setUnnamedAddr(HasUnnamedAddr);
+ GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr(
+ DGV->getUnnamedAddr(), GV.getUnnamedAddr());
+ DGV->setUnnamedAddr(UnnamedAddr);
+ GV.setUnnamedAddr(UnnamedAddr);
}
// Don't want to append to global_ctors list, for example, when we
@@ -670,12 +390,12 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
if (GV.hasAppendingLinkage() && isPerformingImport())
return false;
- if (isPerformingImport() && !doImportAsDefinition(&GV))
- return false;
-
- if (!DGV && !shouldOverrideFromSrc() &&
- (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||
- GV.hasAvailableExternallyLinkage()))
+ if (isPerformingImport()) {
+ if (!doImportAsDefinition(&GV))
+ return false;
+ } else if (!DGV && !shouldOverrideFromSrc() &&
+ (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||
+ GV.hasAvailableExternallyLinkage()))
return false;
if (GV.isDeclaration())
@@ -685,9 +405,8 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
bool LinkFromSrc;
Comdat::SelectionKind SK;
std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];
- if (LinkFromSrc)
- ValuesToLink.insert(&GV);
- return false;
+ if (!LinkFromSrc)
+ return false;
}
bool LinkFromSrc = true;
@@ -698,9 +417,15 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
return false;
}
-void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) {
+void ModuleLinker::addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add) {
+ if (!shouldLinkReferencedLinkOnce())
+ // For ThinLTO we don't import more than what was required.
+ // The client has to guarantee that the linkonce will be availabe at link
+ // time (by promoting it to weak for instance).
+ return;
+
// Add these to the internalize list
- if (!GV.hasLinkOnceLinkage())
+ if (!GV.hasLinkOnceLinkage() && !shouldLinkOnlyNeeded())
return;
if (shouldInternalizeLinkedSymbols())
@@ -710,43 +435,59 @@ void ModuleLinker::addLazyFor(GlobalValue &GV, IRMover::ValueAdder Add) {
const Comdat *SC = GV.getComdat();
if (!SC)
return;
- for (GlobalValue *GV2 : ComdatMembers[SC]) {
- if (!GV2->hasLocalLinkage() && shouldInternalizeLinkedSymbols())
+ for (GlobalValue *GV2 : LazyComdatMembers[SC]) {
+ GlobalValue *DGV = getLinkedToGlobal(GV2);
+ bool LinkFromSrc = true;
+ if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2))
+ return;
+ if (!LinkFromSrc)
+ continue;
+ if (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);
+void ModuleLinker::dropReplacedComdat(
+ GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) {
+ Comdat *C = GV.getComdat();
+ if (!C)
+ return;
+ if (!ReplacedDstComdats.count(C))
+ return;
+ if (GV.use_empty()) {
+ GV.eraseFromParent();
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;
+ if (auto *F = dyn_cast<Function>(&GV)) {
+ F->deleteBody();
+ } else if (auto *Var = dyn_cast<GlobalVariable>(&GV)) {
+ Var->setInitializer(nullptr);
+ } else {
+ auto &Alias = cast<GlobalAlias>(GV);
+ Module &M = *Alias.getParent();
+ PointerType &Ty = *cast<PointerType>(Alias.getType());
+ GlobalValue *Declaration;
+ if (auto *FTy = dyn_cast<FunctionType>(Alias.getValueType())) {
+ Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, "", &M);
+ } else {
+ Declaration =
+ new GlobalVariable(M, Ty.getElementType(), /*isConstant*/ false,
+ GlobalValue::ExternalLinkage,
+ /*Initializer*/ nullptr);
+ }
+ Declaration->takeName(&Alias);
+ Alias.replaceAllUsesWith(Declaration);
+ Alias.eraseFromParent();
+ }
}
bool ModuleLinker::run() {
- for (const auto &SMEC : SrcM.getComdatSymbolTable()) {
+ Module &DstM = Mover.getModule();
+ DenseSet<const Comdat *> ReplacedDstComdats;
+
+ for (const auto &SMEC : SrcM->getComdatSymbolTable()) {
const Comdat &C = SMEC.getValue();
if (ComdatsChosen.count(&C))
continue;
@@ -755,50 +496,79 @@ bool ModuleLinker::run() {
if (getComdatResult(&C, SK, LinkFromSrc))
return true;
ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc);
+
+ if (!LinkFromSrc)
+ continue;
+
+ Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable();
+ Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName());
+ if (DstCI == ComdatSymTab.end())
+ continue;
+
+ // The source comdat is replacing the dest one.
+ const Comdat *DstC = &DstCI->second;
+ ReplacedDstComdats.insert(DstC);
}
- for (GlobalVariable &GV : SrcM.globals())
- if (const Comdat *SC = GV.getComdat())
- ComdatMembers[SC].push_back(&GV);
+ // Alias have to go first, since we are not able to find their comdats
+ // otherwise.
+ for (auto I = DstM.alias_begin(), E = DstM.alias_end(); I != E;) {
+ GlobalAlias &GV = *I++;
+ dropReplacedComdat(GV, ReplacedDstComdats);
+ }
+
+ for (auto I = DstM.global_begin(), E = DstM.global_end(); I != E;) {
+ GlobalVariable &GV = *I++;
+ dropReplacedComdat(GV, ReplacedDstComdats);
+ }
+
+ for (auto I = DstM.begin(), E = DstM.end(); I != E;) {
+ Function &GV = *I++;
+ dropReplacedComdat(GV, ReplacedDstComdats);
+ }
+
+ for (GlobalVariable &GV : SrcM->globals())
+ if (GV.hasLinkOnceLinkage())
+ if (const Comdat *SC = GV.getComdat())
+ LazyComdatMembers[SC].push_back(&GV);
- for (Function &SF : SrcM)
- if (const Comdat *SC = SF.getComdat())
- ComdatMembers[SC].push_back(&SF);
+ for (Function &SF : *SrcM)
+ if (SF.hasLinkOnceLinkage())
+ if (const Comdat *SC = SF.getComdat())
+ LazyComdatMembers[SC].push_back(&SF);
- for (GlobalAlias &GA : SrcM.aliases())
- if (const Comdat *SC = GA.getComdat())
- ComdatMembers[SC].push_back(&GA);
+ for (GlobalAlias &GA : SrcM->aliases())
+ if (GA.hasLinkOnceLinkage())
+ if (const Comdat *SC = GA.getComdat())
+ LazyComdatMembers[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())
+ for (GlobalVariable &GV : SrcM->globals())
if (linkIfNeeded(GV))
return true;
- for (Function &SF : SrcM)
+ for (Function &SF : *SrcM)
if (linkIfNeeded(SF))
return true;
- for (GlobalAlias &GA : SrcM.aliases())
+ 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);
+ for (GlobalValue *GV2 : LazyComdatMembers[SC]) {
+ GlobalValue *DGV = getLinkedToGlobal(GV2);
+ bool LinkFromSrc = true;
+ if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2))
+ return true;
+ if (LinkFromSrc)
+ ValuesToLink.insert(GV2);
+ }
}
if (shouldInternalizeLinkedSymbols()) {
@@ -806,13 +576,21 @@ bool ModuleLinker::run() {
Internalize.insert(GV->getName());
}
- if (Mover.move(SrcM, ValuesToLink.getArrayRef(),
- [this](GlobalValue &GV, IRMover::ValueAdder Add) {
- addLazyFor(GV, Add);
- },
- ValIDToTempMDMap, false))
+ // FIXME: Propagate Errors through to the caller instead of emitting
+ // diagnostics.
+ bool HasErrors = false;
+ if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(),
+ [this](GlobalValue &GV, IRMover::ValueAdder Add) {
+ addLazyFor(GV, Add);
+ })) {
+ handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
+ DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message()));
+ HasErrors = true;
+ });
+ }
+ if (HasErrors)
return true;
- Module &DstM = Mover.getModule();
+
for (auto &P : Internalize) {
GlobalValue *GV = DstM.getNamedValue(P.first());
GV->setLinkage(GlobalValue::InternalLinkage);
@@ -824,30 +602,11 @@ bool ModuleLinker::run() {
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);
+ DenseSet<const GlobalValue *> *GlobalsToImport) {
+ ModuleLinker ModLinker(Mover, std::move(Src), Flags, GlobalsToImport);
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.
//===----------------------------------------------------------------------===//
@@ -863,44 +622,10 @@ bool Linker::linkModules(Module &Dest, std::unique_ptr<Module> Src,
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));
OpenPOWER on IntegriCloud