TypeMapTy &TypeMap;
Module *DstM;
std::vector<GlobalValue *> &LazilyLinkGlobalValues;
- ModuleLinker *ModLinker;
public:
ValueMaterializerTy(TypeMapTy &TypeMap, Module *DstM,
- std::vector<GlobalValue *> &LazilyLinkGlobalValues,
- ModuleLinker *ModLinker)
+ std::vector<GlobalValue *> &LazilyLinkGlobalValues)
: ValueMaterializer(), TypeMap(TypeMap), DstM(DstM),
- LazilyLinkGlobalValues(LazilyLinkGlobalValues), ModLinker(ModLinker) {}
+ LazilyLinkGlobalValues(LazilyLinkGlobalValues) {}
Value *materializeValueFor(Value *V) override;
};
/// For symbol clashes, prefer those from Src.
unsigned Flags;
- /// Function index passed into ModuleLinker for using in function
- /// importing/exporting handling.
- FunctionInfoIndex *ImportIndex;
-
- /// Function to import from source module, all other functions are
- /// imported as declarations instead of definitions.
- Function *ImportFunction;
-
- /// 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;
-
public:
ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM,
- DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags,
- FunctionInfoIndex *Index = nullptr,
- Function *FuncToImport = nullptr)
+ DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags)
: DstM(dstM), SrcM(srcM), TypeMap(Set),
- ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues, this),
- DiagnosticHandler(DiagnosticHandler), Flags(Flags), ImportIndex(Index),
- ImportFunction(FuncToImport), HasExportedFunctions(false) {
- assert((ImportIndex || !ImportFunction) &&
- "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 && !ImportFunction)
- HasExportedFunctions = ImportIndex->hasExportedFunctions(SrcM);
- }
+ ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues),
+ DiagnosticHandler(DiagnosticHandler), Flags(Flags) {}
bool run();
return Flags & Linker::InternalizeLinkedSymbols;
}
- /// Handles cloning of a global values from the source module into
- /// the destination module, including setting the attributes and visibility.
- GlobalValue *copyGlobalValueProto(TypeMapTy &TypeMap, const GlobalValue *SGV,
- const GlobalValue *DGV = nullptr);
-
- /// Check if we should promote the given local value to global scope.
- bool doPromoteLocalToGlobal(const GlobalValue *SGV);
-
private:
bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest,
const GlobalValue &Src);
void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src);
bool linkGlobalValueBody(GlobalValue &Src);
- /// Functions that take care of cloning a specific global value type
- /// into the destination module.
- GlobalVariable *copyGlobalVariableProto(TypeMapTy &TypeMap,
- const GlobalVariable *SGVar);
- Function *copyFunctionProto(TypeMapTy &TypeMap, const Function *SF);
- GlobalValue *copyGlobalAliasProto(TypeMapTy &TypeMap, const GlobalAlias *SGA);
-
- /// Helper methods to check if we are importing from or potentially
- /// exporting from the current source module.
- bool isPerformingImport() { return ImportFunction != nullptr; }
- bool isModuleExporting() { 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);
-
- /// 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);
-
- /// Copies the necessary global value attributes and name from the source
- /// to the newly cloned global value.
- void copyGVAttributes(GlobalValue *NewGV, const GlobalValue *SrcGV);
-
- /// Updates the visibility for the new global cloned from the source
- /// and, if applicable, linked with an existing destination global.
- /// Handles visibility change required for promoted locals.
- void setVisibility(GlobalValue *NewGV, const GlobalValue *SGV,
- const GlobalValue *DGV = nullptr);
-
void linkNamedMDNodes();
void stripReplacedSubprograms();
};
static void forceRenaming(GlobalValue *GV, StringRef Name) {
// If the global doesn't force its name or if it already has the right name,
// there is nothing for us to do.
- // Note that any required local to global promotion should already be done,
- // so promoted locals will not skip this handling as their linkage is no
- // longer local.
if (GV->hasLocalLinkage() || GV->getName() == Name)
return;
/// copy additional attributes (those not needed to construct a GlobalValue)
/// from the SrcGV to the DestGV.
-void ModuleLinker::copyGVAttributes(GlobalValue *NewGV,
- const GlobalValue *SrcGV) {
- auto *GA = dyn_cast<GlobalAlias>(SrcGV);
- // Check for the special case of converting an alias (definition) to a
- // non-alias (declaration). This can happen when we are importing and
- // encounter a weak_any alias (weak_any defs may not be imported, see
- // comments in ModuleLinker::getLinkage) or an alias whose base object is
- // being imported as a declaration. In that case copy the attributes from the
- // base object.
- if (GA && !dyn_cast<GlobalAlias>(NewGV)) {
- assert(isPerformingImport() &&
- (GA->hasWeakAnyLinkage() ||
- !doImportAsDefinition(GA->getBaseObject())));
- NewGV->copyAttributesFrom(GA->getBaseObject());
- } else
- NewGV->copyAttributesFrom(SrcGV);
- forceRenaming(NewGV, getName(SrcGV));
+static void copyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) {
+ DestGV->copyAttributesFrom(SrcGV);
+ forceRenaming(DestGV, SrcGV->getName());
}
static bool isLessConstraining(GlobalValue::VisibilityTypes a,
return false;
}
-bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) {
- if (!isPerformingImport())
- return false;
- // Always import GlobalVariable definitions. The linkage changes
- // described in ModuleLinker::getLinkage ensure the correct behavior (e.g.
- // global variables with external linkage are transformed to
- // available_externally defintions, which are ultimately turned into
- // declaratios after the EliminateAvailableExternally pass).
- if (dyn_cast<GlobalVariable>(SGV) && !SGV->isDeclaration())
- return true;
- // Only import the function requested for importing.
- auto *SF = dyn_cast<Function>(SGV);
- if (SF && SF == ImportFunction)
- return true;
- // Otherwise no.
- return false;
-}
-
-bool ModuleLinker::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 ModuleLinker::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 ModuleLinker::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))
- 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))
- 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 linkGlobalValueProto.
- assert(false && "Cannot import appending linkage variable");
-
- 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))
- 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");
-}
-
/// Loop through the global variables in the src module and merge them into the
/// dest module.
-GlobalVariable *
-ModuleLinker::copyGlobalVariableProto(TypeMapTy &TypeMap,
- const GlobalVariable *SGVar) {
+static GlobalVariable *copyGlobalVariableProto(TypeMapTy &TypeMap, Module &DstM,
+ const GlobalVariable *SGVar) {
// No linking to be performed or linking from the source: simply create an
// identical version of the symbol over in the dest module... the
// initializer will be filled in later by LinkGlobalInits.
GlobalVariable *NewDGV = new GlobalVariable(
- *DstM, TypeMap.get(SGVar->getType()->getElementType()),
- SGVar->isConstant(), getLinkage(SGVar), /*init*/ nullptr, getName(SGVar),
- /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(),
+ DstM, TypeMap.get(SGVar->getType()->getElementType()),
+ SGVar->isConstant(), SGVar->getLinkage(), /*init*/ nullptr,
+ SGVar->getName(), /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(),
SGVar->getType()->getAddressSpace());
return NewDGV;
/// Link the function in the source module into the destination module if
/// needed, setting up mapping information.
-Function *ModuleLinker::copyFunctionProto(TypeMapTy &TypeMap,
- const Function *SF) {
+static Function *copyFunctionProto(TypeMapTy &TypeMap, Module &DstM,
+ const Function *SF) {
// If there is no linkage to be performed or we are linking from the source,
// bring SF over.
- return Function::Create(TypeMap.get(SF->getFunctionType()), getLinkage(SF),
- getName(SF), DstM);
+ return Function::Create(TypeMap.get(SF->getFunctionType()), SF->getLinkage(),
+ SF->getName(), &DstM);
}
/// Set up prototypes for any aliases that come over from the source module.
-GlobalValue *ModuleLinker::copyGlobalAliasProto(TypeMapTy &TypeMap,
- const GlobalAlias *SGA) {
- // If we are importing and encounter a weak_any alias, or an alias to
- // an object being imported as a declaration, we must import the alias
- // as a declaration as well, which involves converting it to a non-alias.
- // See comments in ModuleLinker::getLinkage for why we cannot import
- // weak_any defintions.
- if (isPerformingImport() && (SGA->hasWeakAnyLinkage() ||
- !doImportAsDefinition(SGA->getBaseObject()))) {
- // Need to convert to declaration. All aliases must be definitions.
- const GlobalValue *GVal = SGA->getBaseObject();
- GlobalValue *NewGV;
- if (auto *GVar = dyn_cast<GlobalVariable>(GVal))
- NewGV = copyGlobalVariableProto(TypeMap, GVar);
- else {
- auto *F = dyn_cast<Function>(GVal);
- assert(F);
- NewGV = copyFunctionProto(TypeMap, F);
- }
- // Set the linkage to ExternalWeak, see also comments in
- // ModuleLinker::getLinkage.
- if (SGA->hasWeakAnyLinkage())
- NewGV->setLinkage(GlobalValue::ExternalWeakLinkage);
- // Don't attempt to link body, needs to be a declaration.
- DoNotLinkFromSource.insert(SGA);
- return NewGV;
- }
+static GlobalAlias *copyGlobalAliasProto(TypeMapTy &TypeMap, Module &DstM,
+ const GlobalAlias *SGA) {
// If there is no linkage to be performed or we're linking from the source,
// bring over SGA.
auto *Ty = TypeMap.get(SGA->getValueType());
return GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(),
- getLinkage(SGA), getName(SGA), DstM);
+ SGA->getLinkage(), SGA->getName(), &DstM);
}
-void ModuleLinker::setVisibility(GlobalValue *NewGV, const GlobalValue *SGV,
- const GlobalValue *DGV) {
- GlobalValue::VisibilityTypes Visibility = SGV->getVisibility();
- if (DGV)
- Visibility = isLessConstraining(Visibility, DGV->getVisibility())
- ? DGV->getVisibility()
- : Visibility;
- // For promoted locals, mark them hidden so that they can later be
- // stripped from the symbol table to reduce bloat.
- if (SGV->hasLocalLinkage() && doPromoteLocalToGlobal(SGV))
- Visibility = GlobalValue::HiddenVisibility;
- NewGV->setVisibility(Visibility);
-}
-
-GlobalValue *ModuleLinker::copyGlobalValueProto(TypeMapTy &TypeMap,
- const GlobalValue *SGV,
- const GlobalValue *DGV) {
+static GlobalValue *copyGlobalValueProto(TypeMapTy &TypeMap, Module &DstM,
+ const GlobalValue *SGV) {
GlobalValue *NewGV;
if (auto *SGVar = dyn_cast<GlobalVariable>(SGV))
- NewGV = copyGlobalVariableProto(TypeMap, SGVar);
+ NewGV = copyGlobalVariableProto(TypeMap, DstM, SGVar);
else if (auto *SF = dyn_cast<Function>(SGV))
- NewGV = copyFunctionProto(TypeMap, SF);
+ NewGV = copyFunctionProto(TypeMap, DstM, SF);
else
- NewGV = copyGlobalAliasProto(TypeMap, cast<GlobalAlias>(SGV));
+ NewGV = copyGlobalAliasProto(TypeMap, DstM, cast<GlobalAlias>(SGV));
copyGVAttributes(NewGV, SGV);
- setVisibility(NewGV, SGV, DGV);
return NewGV;
}
if (!SGV)
return nullptr;
- GlobalValue *DGV = ModLinker->copyGlobalValueProto(TypeMap, SGV);
+ GlobalValue *DGV = copyGlobalValueProto(TypeMap, *DstM, SGV);
if (Comdat *SC = SGV->getComdat()) {
if (auto *DGO = dyn_cast<GlobalObject>(DGV)) {
// We always have to add Src if it has appending linkage.
if (Src.hasAppendingLinkage()) {
- // Caller should have already determined that we can't link from source
- // when importing (see comments in linkGlobalValueProto).
- 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 the function requested
- // for importing. For variables, decide below normally.
- LinkFromSrc = (&Src == ImportFunction);
- 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.
GlobalValue *DGV = getLinkedToGlobal(SGV);
// Handle the ultra special appending linkage case first.
- assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage());
- if (SGV->hasAppendingLinkage() && isPerformingImport()) {
- // 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).
- DoNotLinkFromSource.insert(SGV);
- return false;
- }
if (DGV && DGV->hasAppendingLinkage())
return linkAppendingVarProto(cast<GlobalVariable>(DGV),
cast<GlobalVariable>(SGV));
bool LinkFromSrc = true;
Comdat *C = nullptr;
+ GlobalValue::VisibilityTypes Visibility = SGV->getVisibility();
bool HasUnnamedAddr = SGV->hasUnnamedAddr();
if (const Comdat *SC = SGV->getComdat()) {
ConstantExpr::getBitCast(DGV, TypeMap.get(SGV->getType()));
}
- if (DGV)
+ if (DGV) {
+ Visibility = isLessConstraining(Visibility, DGV->getVisibility())
+ ? DGV->getVisibility()
+ : Visibility;
HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr();
+ }
if (!LinkFromSrc && !DGV)
return false;
GlobalValue *NewGV;
if (!LinkFromSrc) {
NewGV = DGV;
- // When linking from source we setVisibility from copyGlobalValueProto.
- setVisibility(NewGV, SGV, DGV);
} else {
// If the GV is to be lazily linked, don't create it just yet.
// The ValueMaterializerTy will deal with creating it if it's used.
- if (!DGV && !shouldOverrideFromSrc() && SGV != ImportFunction &&
+ if (!DGV && !shouldOverrideFromSrc() &&
(SGV->hasLocalLinkage() || SGV->hasLinkOnceLinkage() ||
SGV->hasAvailableExternallyLinkage())) {
DoNotLinkFromSource.insert(SGV);
return false;
}
- NewGV = copyGlobalValueProto(TypeMap, SGV, DGV);
+ NewGV = copyGlobalValueProto(TypeMap, *DstM, SGV);
if (DGV && isa<Function>(DGV))
if (auto *NewF = dyn_cast<Function>(NewGV))
}
NewGV->setUnnamedAddr(HasUnnamedAddr);
+ NewGV->setVisibility(Visibility);
if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) {
if (C)
if (DoNotLinkFromSource.count(&SF))
continue;
- // When importing, only materialize the function requested for import.
- if (isPerformingImport() && &SF != ImportFunction)
- continue;
-
if (linkGlobalValueBody(SF))
return true;
}
while (!LazilyLinkGlobalValues.empty()) {
GlobalValue *SGV = LazilyLinkGlobalValues.back();
LazilyLinkGlobalValues.pop_back();
- if (isPerformingImport() && !doImportAsDefinition(SGV))
- continue;
// Skip declarations that ValueMaterializer may have created in
// case we link in only some of SrcM.
Composite = nullptr;
}
-bool Linker::linkInModule(Module *Src, unsigned Flags, FunctionInfoIndex *Index,
- Function *FuncToImport) {
+bool Linker::linkInModule(Module *Src, unsigned Flags) {
ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src,
- DiagnosticHandler, Flags, Index, FuncToImport);
+ DiagnosticHandler, Flags);
bool RetCode = TheLinker.run();
Composite->dropTriviallyDeadConstantArrays();
return RetCode;
+++ /dev/null
-; Do setup work for all below tests: generate bitcode and combined index
-; RUN: llvm-as -function-summary %s -o %t.bc
-; RUN: llvm-as -function-summary %p/Inputs/funcimport.ll -o %t2.bc
-; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
-
-; Ensure statics are promoted/renamed correctly from this file (all but
-; constant variable need promotion).
-; RUN: llvm-link %t.bc -functionindex=%t3.thinlto.bc -S | FileCheck %s --check-prefix=EXPORTSTATIC
-; EXPORTSTATIC: @staticvar.llvm.1 = hidden global
-; EXPORTSTATIC: @staticconstvar = internal unnamed_addr constant
-; EXPORTSTATIC: @P.llvm.1 = hidden global void ()* null
-; EXPORTSTATIC: define hidden i32 @staticfunc.llvm.1
-; EXPORTSTATIC: define hidden void @staticfunc2.llvm.1
-
-; Ensure that both weak alias to an imported function and strong alias to a
-; non-imported function are correctly turned into declarations.
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB1
-; IMPORTGLOB1: define available_externally void @globalfunc1
-; IMPORTGLOB1: declare void @globalfunc2
-; IMPORTGLOB1: declare extern_weak void @weakalias
-; IMPORTGLOB1: declare void @analias
-
-; Ensure that weak alias to a non-imported function is correctly
-; turned into a declaration, but that strong alias to an imported function
-; is imported as alias.
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB2
-; IMPORTGLOB2: @analias = alias void (...), bitcast (void ()* @globalfunc2
-; IMPORTGLOB2: declare void @globalfunc1
-; IMPORTGLOB2: define available_externally void @globalfunc2
-; IMPORTGLOB2: declare extern_weak void @weakalias
-
-; Ensure that strong alias imported in second pass of importing ends up
-; as an alias.
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc1:%t.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB3
-; IMPORTGLOB3: @analias = alias void (...), bitcast (void ()* @globalfunc2
-; IMPORTGLOB3: define available_externally void @globalfunc1
-; IMPORTGLOB3: define available_externally void @globalfunc2
-; IMPORTGLOB3: declare extern_weak void @weakalias
-
-; Ensure that strong alias imported in first pass of importing ends up
-; as an alias, and that seeing the alias definition during a second inlining
-; pass is handled correctly.
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc2:%t.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB4
-; IMPORTGLOB4: @analias = alias void (...), bitcast (void ()* @globalfunc2
-; IMPORTGLOB4: define available_externally void @globalfunc2
-; IMPORTGLOB4: define available_externally void @globalfunc1
-; IMPORTGLOB4: declare extern_weak void @weakalias
-
-; Ensure that imported static variable and function references are correctly
-; promoted and renamed (including static constant variable).
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referencestatics:%t.bc -S | FileCheck %s --check-prefix=IMPORTSTATIC
-; IMPORTSTATIC: @staticvar.llvm.1 = available_externally hidden global
-; IMPORTSTATIC: @staticconstvar.llvm.1 = internal unnamed_addr constant
-; IMPORTSTATIC: define available_externally i32 @referencestatics
-; IMPORTSTATIC: %call = call i32 @staticfunc.llvm.1
-; IMPORTSTATIC: %0 = load i32, i32* @staticvar.llvm.1
-; IMPORTSTATIC: declare hidden i32 @staticfunc.llvm.1
-
-; Ensure that imported global (external) function and variable references
-; are handled correctly (including referenced variable imported as
-; available_externally definition)
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referenceglobals:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOBALS
-; IMPORTGLOBALS: @globalvar = available_externally global
-; IMPORTGLOBALS: declare void @globalfunc1()
-; IMPORTGLOBALS: define available_externally i32 @referenceglobals
-
-; Ensure that common variable correctly imported as common defition.
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referencecommon:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMMON
-; IMPORTCOMMON: @commonvar = common global
-; IMPORTCOMMON: define available_externally i32 @referencecommon
-
-; Ensure that imported static function pointer correctly promoted and renamed.
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=callfuncptr:%t.bc -S | FileCheck %s --check-prefix=IMPORTFUNCPTR
-; IMPORTFUNCPTR: @P.llvm.1 = available_externally hidden global void ()* null
-; IMPORTFUNCPTR: define available_externally void @callfuncptr
-; IMPORTFUNCPTR: %0 = load void ()*, void ()** @P.llvm.1
-
-; Ensure that imported weak function reference/definition handled properly.
-; Imported weak_any definition should be skipped with warning, and imported
-; reference should turned into an external_weak declaration.
-; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=callweakfunc:%t.bc -import=weakfunc:%t.bc -S 2>&1 | FileCheck %s --check-prefix=IMPORTWEAKFUNC
-; IMPORTWEAKFUNC: Ignoring import request for weak-any function weakfunc
-; IMPORTWEAKFUNC: declare extern_weak void @weakfunc
-; IMPORTWEAKFUNC: define available_externally void @callweakfunc
-
-@globalvar = global i32 1, align 4
-@staticvar = internal global i32 1, align 4
-@staticconstvar = internal unnamed_addr constant [2 x i32] [i32 10, i32 20], align 4
-@commonvar = common global i32 0, align 4
-@P = internal global void ()* null, align 8
-
-@weakalias = weak alias void (...), bitcast (void ()* @globalfunc1 to void (...)*)
-@analias = alias void (...), bitcast (void ()* @globalfunc2 to void (...)*)
-
-define void @globalfunc1() #0 {
-entry:
- ret void
-}
-
-define void @globalfunc2() #0 {
-entry:
- ret void
-}
-
-define i32 @referencestatics(i32 %i) #0 {
-entry:
- %i.addr = alloca i32, align 4
- store i32 %i, i32* %i.addr, align 4
- %call = call i32 @staticfunc()
- %0 = load i32, i32* @staticvar, align 4
- %add = add nsw i32 %call, %0
- %1 = load i32, i32* %i.addr, align 4
- %idxprom = sext i32 %1 to i64
- %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* @staticconstvar, i64 0, i64 %idxprom
- %2 = load i32, i32* %arrayidx, align 4
- %add1 = add nsw i32 %add, %2
- ret i32 %add1
-}
-
-define i32 @referenceglobals(i32 %i) #0 {
-entry:
- %i.addr = alloca i32, align 4
- store i32 %i, i32* %i.addr, align 4
- call void @globalfunc1()
- %0 = load i32, i32* @globalvar, align 4
- ret i32 %0
-}
-
-define i32 @referencecommon(i32 %i) #0 {
-entry:
- %i.addr = alloca i32, align 4
- store i32 %i, i32* %i.addr, align 4
- %0 = load i32, i32* @commonvar, align 4
- ret i32 %0
-}
-
-define void @setfuncptr() #0 {
-entry:
- store void ()* @staticfunc2, void ()** @P, align 8
- ret void
-}
-
-define void @callfuncptr() #0 {
-entry:
- %0 = load void ()*, void ()** @P, align 8
- call void %0()
- ret void
-}
-
-define weak void @weakfunc() #0 {
-entry:
- ret void
-}
-
-define void @callweakfunc() #0 {
-entry:
- call void @weakfunc()
- ret void
-}
-
-define internal i32 @staticfunc() #0 {
-entry:
- ret i32 1
-}
-
-define internal void @staticfunc2() #0 {
-entry:
- ret void
-}
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
-#include "llvm/IR/FunctionInfo.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
-#include "llvm/Object/FunctionIndexObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
cl::desc(
"input bitcode file which can override previously defined symbol(s)"));
-// Option to simulate function importing for testing. This enables using
-// llvm-link to simulate ThinLTO backend processes.
-static cl::list<std::string> Imports(
- "import", cl::ZeroOrMore, cl::value_desc("function:filename"),
- cl::desc("Pair of function name and filename, where function should be "
- "imported from bitcode in filename"));
-
-// Option to support testing of function importing. The function index
-// must be specified in the case were we request imports via the -import
-// option, as well as when compiling any module with functions that may be
-// exported (imported by a different llvm-link -import invocation), to ensure
-// consistent promotion and renaming of locals.
-static cl::opt<std::string> FunctionIndex("functionindex",
- cl::desc("Function index filename"),
- cl::init(""),
- cl::value_desc("filename"));
-
static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
cl::value_desc("filename"));
errs() << '\n';
}
-/// Load a function index if requested by the -functionindex option.
-static ErrorOr<std::unique_ptr<FunctionInfoIndex>>
-loadIndex(LLVMContext &Context, const Module *ExportingModule = nullptr) {
- assert(!FunctionIndex.empty());
- ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
- MemoryBuffer::getFileOrSTDIN(FunctionIndex);
- std::error_code EC = FileOrErr.getError();
- if (EC)
- return EC;
- MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
- ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
- object::FunctionIndexObjectFile::create(BufferRef, Context,
- ExportingModule);
- EC = ObjOrErr.getError();
- if (EC)
- return EC;
-
- object::FunctionIndexObjectFile &Obj = **ObjOrErr;
- return Obj.takeIndex();
-}
-
-/// Import any functions requested via the -import option.
-static bool importFunctions(const char *argv0, LLVMContext &Context,
- Linker &L) {
- for (const auto &Import : Imports) {
- // Identify the requested function and its bitcode source file.
- size_t Idx = Import.find(':');
- if (Idx == std::string::npos) {
- errs() << "Import parameter bad format: " << Import << "\n";
- return false;
- }
- std::string FunctionName = Import.substr(0, Idx);
- std::string FileName = Import.substr(Idx + 1, std::string::npos);
-
- // Load the specified source module.
- std::unique_ptr<Module> M = loadFile(argv0, FileName, Context);
- if (!M.get()) {
- errs() << argv0 << ": error loading file '" << FileName << "'\n";
- return false;
- }
-
- if (verifyModule(*M, &errs())) {
- errs() << argv0 << ": " << FileName
- << ": error: input module is broken!\n";
- return false;
- }
-
- Function *F = M->getFunction(FunctionName);
- if (!F) {
- errs() << "Ignoring import request for non-existent function "
- << FunctionName << " from " << FileName << "\n";
- continue;
- }
- // We cannot import weak_any functions without possibly affecting the
- // order they are seen and selected by the linker, changing program
- // semantics.
- if (F->hasWeakAnyLinkage()) {
- errs() << "Ignoring import request for weak-any function " << FunctionName
- << " from " << FileName << "\n";
- continue;
- }
-
- if (Verbose)
- errs() << "Importing " << FunctionName << " from " << FileName << "\n";
-
- std::unique_ptr<FunctionInfoIndex> Index;
- if (!FunctionIndex.empty()) {
- ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
- loadIndex(Context);
- std::error_code EC = IndexOrErr.getError();
- if (EC) {
- errs() << EC.message() << '\n';
- return false;
- }
- Index = std::move(IndexOrErr.get());
- }
-
- // Link in the specified function.
- if (L.linkInModule(M.get(), false, Index.get(), F))
- return false;
- }
- return true;
-}
-
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
const cl::list<std::string> &Files,
unsigned Flags) {
return false;
}
- // If a function index is supplied, load it so linkInModule can treat
- // local functions/variables as exported and promote if necessary.
- std::unique_ptr<FunctionInfoIndex> Index;
- if (!FunctionIndex.empty()) {
- ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
- loadIndex(Context, &*M);
- std::error_code EC = IndexOrErr.getError();
- if (EC) {
- errs() << EC.message() << '\n';
- return false;
- }
- Index = std::move(IndexOrErr.get());
- }
-
if (Verbose)
errs() << "Linking in '" << File << "'\n";
- if (L.linkInModule(M.get(), ApplicableFlags, Index.get()))
+ if (L.linkInModule(M.get(), ApplicableFlags))
return false;
// All linker flags apply to linking of subsequent files.
ApplicableFlags = Flags;
Flags | Linker::Flags::OverrideFromSrc))
return 1;
- // Import any functions requested via -import
- if (!importFunctions(argv[0], Context, L))
- return 1;
-
if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;
std::error_code EC;