/// 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,
+ GlobalValue *copyGlobalValueProto(const GlobalValue *SGV,
const GlobalValue *DGV, bool ForDefinition);
/// Check if we should promote the given local value to global scope.
void upgradeMismatchedGlobals();
bool linkIfNeeded(GlobalValue &GV);
- bool linkAppendingVarProto(GlobalVariable *DstGV,
- const GlobalVariable *SrcGV);
+ Constant *linkAppendingVarProto(GlobalVariable *DstGV,
+ const GlobalVariable *SrcGV);
- bool linkGlobalValueProto(GlobalValue *GV);
+ Constant *linkGlobalValueProto(GlobalValue *GV);
bool linkModuleFlagsMetadata();
void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &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);
+ GlobalVariable *copyGlobalVariableProto(const GlobalVariable *SGVar);
+ Function *copyFunctionProto(const Function *SF);
+ GlobalValue *copyGlobalAliasProto(const GlobalAlias *SGA);
/// Helper methods to check if we are importing from or potentially
/// exporting from the current source module.
// 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.
- llvm_unreachable("Cannot import appending linkage variable");
+ // by linkIfNeeded, and we will assert in shouldLinkFromSource
+ // if we try to import, so we simply return AppendingLinkage here
+ // as this helper is called more widely in getLinkedToGlobal.
+ return GlobalValue::AppendingLinkage;
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
/// Loop through the global variables in the src module and merge them into the
/// dest module.
GlobalVariable *
-ModuleLinker::copyGlobalVariableProto(TypeMapTy &TypeMap,
- const GlobalVariable *SGVar) {
+ModuleLinker::copyGlobalVariableProto(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.
/// 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) {
+Function *ModuleLinker::copyFunctionProto(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()),
}
/// Set up prototypes for any aliases that come over from the source module.
-GlobalValue *ModuleLinker::copyGlobalAliasProto(TypeMapTy &TypeMap,
- const GlobalAlias *SGA) {
+GlobalValue *ModuleLinker::copyGlobalAliasProto(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());
NewGV->setVisibility(Visibility);
}
-GlobalValue *ModuleLinker::copyGlobalValueProto(TypeMapTy &TypeMap,
- const GlobalValue *SGV,
+GlobalValue *ModuleLinker::copyGlobalValueProto(const GlobalValue *SGV,
const GlobalValue *DGV,
bool ForDefinition) {
GlobalValue *NewGV;
if (auto *SGVar = dyn_cast<GlobalVariable>(SGV)) {
- NewGV = copyGlobalVariableProto(TypeMap, SGVar);
+ NewGV = copyGlobalVariableProto(SGVar);
} else if (auto *SF = dyn_cast<Function>(SGV)) {
- NewGV = copyFunctionProto(TypeMap, SF);
+ NewGV = copyFunctionProto(SF);
} else {
if (ForDefinition)
- NewGV = copyGlobalAliasProto(TypeMap, cast<GlobalAlias>(SGV));
+ NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV));
else
NewGV = new GlobalVariable(
DstM, TypeMap.get(SGV->getType()->getElementType()),
if (!SGV)
return nullptr;
- linkGlobalValueProto(SGV);
- return ValueMap[SGV];
+ return linkGlobalValueProto(SGV);
}
void ValueMaterializerTy::materializeInitFor(GlobalValue *New,
// 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).
+ // Should have prevented importing for appending linkage in linkIfNeeded.
assert(!isPerformingImport());
LinkFromSrc = true;
return false;
/// If there were any appending global variables, link them together now.
/// Return true on error.
-bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
- const GlobalVariable *SrcGV) {
+Constant *ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
+ const GlobalVariable *SrcGV) {
ArrayType *SrcTy =
cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType()));
Type *EltTy = SrcTy->getElementType();
if (DstGV) {
ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType());
- if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
- return emitError(
+ if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) {
+ emitError(
"Linking globals named '" + SrcGV->getName() +
"': can only link appending global with another appending global!");
+ return nullptr;
+ }
// Check to see that they two arrays agree on type.
- if (EltTy != DstTy->getElementType())
- return emitError("Appending variables with different element types!");
- if (DstGV->isConstant() != SrcGV->isConstant())
- return emitError("Appending variables linked with different const'ness!");
+ if (EltTy != DstTy->getElementType()) {
+ emitError("Appending variables with different element types!");
+ return nullptr;
+ }
+ if (DstGV->isConstant() != SrcGV->isConstant()) {
+ emitError("Appending variables linked with different const'ness!");
+ return nullptr;
+ }
- if (DstGV->getAlignment() != SrcGV->getAlignment())
- return emitError(
+ if (DstGV->getAlignment() != SrcGV->getAlignment()) {
+ emitError(
"Appending variables with different alignment need to be linked!");
+ return nullptr;
+ }
- if (DstGV->getVisibility() != SrcGV->getVisibility())
- return emitError(
+ if (DstGV->getVisibility() != SrcGV->getVisibility()) {
+ emitError(
"Appending variables with different visibility need to be linked!");
+ return nullptr;
+ }
- if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr())
- return emitError(
+ if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr()) {
+ emitError(
"Appending variables with different unnamed_addr need to be linked!");
+ return nullptr;
+ }
- if (StringRef(DstGV->getSection()) != SrcGV->getSection())
- return emitError(
+ if (StringRef(DstGV->getSection()) != SrcGV->getSection()) {
+ emitError(
"Appending variables with different section name need to be linked!");
+ return nullptr;
+ }
}
SmallVector<Constant *, 16> DstElements;
// Propagate alignment, visibility and section info.
copyGVAttributes(NG, SrcGV);
- // Replace any uses of the two global variables with uses of the new
- // global.
- ValueMap[SrcGV] = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
+ Constant *Ret = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
+
+ // Stop recursion.
+ ValueMap[SrcGV] = Ret;
for (auto *V : SrcElements) {
DstElements.push_back(
NG->setInitializer(ConstantArray::get(NewType, DstElements));
+ // Replace any uses of the two global variables with uses of the new
+ // global.
if (DstGV) {
DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType()));
DstGV->eraseFromParent();
}
- return false;
+ return Ret;
}
-bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {
+Constant *ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {
GlobalValue *DGV = getLinkedToGlobal(SGV);
// Handle the ultra special appending linkage case first.
assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage());
- if (SGV->hasAppendingLinkage())
+ if (SGV->hasAppendingLinkage()) {
+ // Should have prevented importing for appending linkage in linkIfNeeded.
+ assert(!isPerformingImport());
return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV),
cast<GlobalVariable>(SGV));
+ }
bool LinkFromSrc = true;
Comdat *C = nullptr;
LinkFromSrc = true;
} else if (DGV) {
if (shouldLinkFromSource(LinkFromSrc, *DGV, *SGV))
- return true;
- }
-
- if (!LinkFromSrc && DGV) {
- // Make sure to remember this mapping.
- ValueMap[SGV] = ConstantExpr::getBitCast(DGV, TypeMap.get(SGV->getType()));
+ return nullptr;
}
if (DGV)
// metadata linking), don't link in the global value due to this
// reference, simply map it to null.
if (DoneLinkingBodies)
- return false;
+ return nullptr;
- NewGV = copyGlobalValueProto(TypeMap, SGV, DGV, LinkFromSrc);
+ NewGV = copyGlobalValueProto(SGV, DGV, LinkFromSrc);
}
NewGV->setUnnamedAddr(HasUnnamedAddr);
NewGVar->setConstant(false);
}
- // Make sure to remember this mapping.
- if (NewGV != DGV) {
- if (DGV) {
- DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGV->getType()));
- DGV->eraseFromParent();
- }
- ValueMap[SGV] = NewGV;
+ if (NewGV != DGV && DGV) {
+ DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGV->getType()));
+ DGV->eraseFromParent();
}
- return false;
+ return ConstantExpr::getBitCast(NewGV, TypeMap.get(SGV->getType()));
}
/// Update the initializers in the Dest module now that all globals that may be
// are linked in. Otherwise, linkonce and other lazy linked GVs will
// not be materialized if they aren't referenced.
for (auto *SGV : ComdatMembers[SC]) {
- auto *DGV = cast_or_null<GlobalValue>(ValueMap[SGV]);
+ auto *DGV = cast_or_null<GlobalValue>(ValueMap.lookup(SGV));
if (DGV && !DGV->isDeclaration())
continue;
MapValue(SGV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer);
}
}
-Linker::Linker(Module &M)
- : Linker(M, [this](const DiagnosticInfo &DI) {
- Composite.getContext().diagnose(DI);
- }) {}
-
bool Linker::linkInModule(Module &Src, unsigned Flags,
const FunctionInfoIndex *Index,
DenseSet<const GlobalValue *> *FunctionsToImport) {
return L.linkInModule(Src, Flags);
}
-bool Linker::linkModules(Module &Dest, Module &Src, unsigned Flags) {
- Linker L(Dest);
- return L.linkInModule(Src, Flags);
-}
-
//===----------------------------------------------------------------------===//
// C API.
//===----------------------------------------------------------------------===//