mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Use references now that it is natural to do so.
The linker never takes ownership of a module or changes which module it is refering to, making it natural to use references. llvm-svn: 254449
This commit is contained in:
parent
91b4595716
commit
e3fda2ca99
@ -68,10 +68,10 @@ public:
|
|||||||
InternalizeLinkedSymbols = (1 << 2)
|
InternalizeLinkedSymbols = (1 << 2)
|
||||||
};
|
};
|
||||||
|
|
||||||
Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler);
|
Linker(Module &M, DiagnosticHandlerFunction DiagnosticHandler);
|
||||||
Linker(Module *M);
|
Linker(Module &M);
|
||||||
|
|
||||||
Module *getModule() const { return Composite; }
|
Module &getModule() const { return Composite; }
|
||||||
|
|
||||||
/// \brief Link \p Src into the composite. The source is destroyed.
|
/// \brief Link \p Src into the composite. The source is destroyed.
|
||||||
/// Passing OverrideSymbols as true will have symbols from Src
|
/// Passing OverrideSymbols as true will have symbols from Src
|
||||||
@ -80,19 +80,19 @@ public:
|
|||||||
/// is passed. If a \p FuncToImport is provided, only that single
|
/// is passed. If a \p FuncToImport is provided, only that single
|
||||||
/// function is imported from the source module.
|
/// function is imported from the source module.
|
||||||
/// Returns true on error.
|
/// Returns true on error.
|
||||||
bool linkInModule(Module *Src, unsigned Flags = Flags::None,
|
bool linkInModule(Module &Src, unsigned Flags = Flags::None,
|
||||||
const FunctionInfoIndex *Index = nullptr,
|
const FunctionInfoIndex *Index = nullptr,
|
||||||
Function *FuncToImport = nullptr);
|
Function *FuncToImport = nullptr);
|
||||||
|
|
||||||
static bool LinkModules(Module *Dest, Module *Src,
|
static bool linkModules(Module &Dest, Module &Src,
|
||||||
DiagnosticHandlerFunction DiagnosticHandler,
|
DiagnosticHandlerFunction DiagnosticHandler,
|
||||||
unsigned Flags = Flags::None);
|
unsigned Flags = Flags::None);
|
||||||
|
|
||||||
static bool LinkModules(Module *Dest, Module *Src,
|
static bool linkModules(Module &Dest, Module &Src,
|
||||||
unsigned Flags = Flags::None);
|
unsigned Flags = Flags::None);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Module *Composite;
|
Module &Composite;
|
||||||
|
|
||||||
IdentifiedStructTypeSet IdentifiedStructTypes;
|
IdentifiedStructTypeSet IdentifiedStructTypes;
|
||||||
|
|
||||||
|
@ -67,14 +67,14 @@ const char* LTOCodeGenerator::getVersionString() {
|
|||||||
LTOCodeGenerator::LTOCodeGenerator()
|
LTOCodeGenerator::LTOCodeGenerator()
|
||||||
: Context(getGlobalContext()),
|
: Context(getGlobalContext()),
|
||||||
MergedModule(new Module("ld-temp.o", Context)),
|
MergedModule(new Module("ld-temp.o", Context)),
|
||||||
IRLinker(new Linker(MergedModule.get())) {
|
IRLinker(new Linker(*MergedModule)) {
|
||||||
initializeLTOPasses();
|
initializeLTOPasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
LTOCodeGenerator::LTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
|
LTOCodeGenerator::LTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
|
||||||
: OwnedContext(std::move(Context)), Context(*OwnedContext),
|
: OwnedContext(std::move(Context)), Context(*OwnedContext),
|
||||||
MergedModule(new Module("ld-temp.o", *OwnedContext)),
|
MergedModule(new Module("ld-temp.o", *OwnedContext)),
|
||||||
IRLinker(new Linker(MergedModule.get())) {
|
IRLinker(new Linker(*MergedModule)) {
|
||||||
initializeLTOPasses();
|
initializeLTOPasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ bool LTOCodeGenerator::addModule(LTOModule *Mod) {
|
|||||||
assert(&Mod->getModule().getContext() == &Context &&
|
assert(&Mod->getModule().getContext() == &Context &&
|
||||||
"Expected module in same context");
|
"Expected module in same context");
|
||||||
|
|
||||||
bool ret = IRLinker->linkInModule(&Mod->getModule());
|
bool ret = IRLinker->linkInModule(Mod->getModule());
|
||||||
|
|
||||||
const std::vector<const char *> &undefs = Mod->getAsmUndefinedRefs();
|
const std::vector<const char *> &undefs = Mod->getAsmUndefinedRefs();
|
||||||
for (int i = 0, e = undefs.size(); i != e; ++i)
|
for (int i = 0, e = undefs.size(); i != e; ++i)
|
||||||
@ -130,7 +130,7 @@ void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> Mod) {
|
|||||||
AsmUndefinedRefs.clear();
|
AsmUndefinedRefs.clear();
|
||||||
|
|
||||||
MergedModule = Mod->takeModule();
|
MergedModule = Mod->takeModule();
|
||||||
IRLinker = make_unique<Linker>(MergedModule.get());
|
IRLinker = make_unique<Linker>(*MergedModule);
|
||||||
|
|
||||||
const std::vector<const char*> &Undefs = Mod->getAsmUndefinedRefs();
|
const std::vector<const char*> &Undefs = Mod->getAsmUndefinedRefs();
|
||||||
for (int I = 0, E = Undefs.size(); I != E; ++I)
|
for (int I = 0, E = Undefs.size(); I != E; ++I)
|
||||||
|
@ -390,7 +390,8 @@ void LinkDiagnosticInfo::print(DiagnosticPrinter &DP) const { DP << Msg; }
|
|||||||
/// This is an implementation class for the LinkModules function, which is the
|
/// This is an implementation class for the LinkModules function, which is the
|
||||||
/// entrypoint for this file.
|
/// entrypoint for this file.
|
||||||
class ModuleLinker {
|
class ModuleLinker {
|
||||||
Module *DstM, *SrcM;
|
Module &DstM;
|
||||||
|
Module &SrcM;
|
||||||
|
|
||||||
TypeMapTy TypeMap;
|
TypeMapTy TypeMap;
|
||||||
ValueMaterializerTy ValMaterializer;
|
ValueMaterializerTy ValMaterializer;
|
||||||
@ -431,11 +432,11 @@ class ModuleLinker {
|
|||||||
bool HasError = false;
|
bool HasError = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM,
|
ModuleLinker(Module &DstM, Linker::IdentifiedStructTypeSet &Set, Module &SrcM,
|
||||||
DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags,
|
DiagnosticHandlerFunction DiagnosticHandler, unsigned Flags,
|
||||||
const FunctionInfoIndex *Index = nullptr,
|
const FunctionInfoIndex *Index = nullptr,
|
||||||
Function *FuncToImport = nullptr)
|
Function *FuncToImport = nullptr)
|
||||||
: DstM(dstM), SrcM(srcM), TypeMap(Set), ValMaterializer(this),
|
: DstM(DstM), SrcM(SrcM), TypeMap(Set), ValMaterializer(this),
|
||||||
DiagnosticHandler(DiagnosticHandler), Flags(Flags), ImportIndex(Index),
|
DiagnosticHandler(DiagnosticHandler), Flags(Flags), ImportIndex(Index),
|
||||||
ImportFunction(FuncToImport), HasExportedFunctions(false),
|
ImportFunction(FuncToImport), HasExportedFunctions(false),
|
||||||
DoneLinkingBodies(false) {
|
DoneLinkingBodies(false) {
|
||||||
@ -446,7 +447,7 @@ public:
|
|||||||
// backend compilation, and we need to see if it has functions that
|
// backend compilation, and we need to see if it has functions that
|
||||||
// may be exported to another backend compilation.
|
// may be exported to another backend compilation.
|
||||||
if (ImportIndex && !ImportFunction)
|
if (ImportIndex && !ImportFunction)
|
||||||
HasExportedFunctions = ImportIndex->hasExportedFunctions(SrcM);
|
HasExportedFunctions = ImportIndex->hasExportedFunctions(&SrcM);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool run();
|
bool run();
|
||||||
@ -485,7 +486,7 @@ private:
|
|||||||
DiagnosticHandler(LinkDiagnosticInfo(DS_Warning, Message));
|
DiagnosticHandler(LinkDiagnosticInfo(DS_Warning, Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getComdatLeader(Module *M, StringRef ComdatName,
|
bool getComdatLeader(Module &M, StringRef ComdatName,
|
||||||
const GlobalVariable *&GVar);
|
const GlobalVariable *&GVar);
|
||||||
bool computeResultingSelectionKind(StringRef ComdatName,
|
bool computeResultingSelectionKind(StringRef ComdatName,
|
||||||
Comdat::SelectionKind Src,
|
Comdat::SelectionKind Src,
|
||||||
@ -508,7 +509,7 @@ private:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Otherwise see if we have a match in the destination module's symtab.
|
// Otherwise see if we have a match in the destination module's symtab.
|
||||||
GlobalValue *DGV = DstM->getNamedValue(getName(SrcGV));
|
GlobalValue *DGV = DstM.getNamedValue(getName(SrcGV));
|
||||||
if (!DGV)
|
if (!DGV)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@ -793,7 +794,7 @@ ModuleLinker::copyGlobalVariableProto(TypeMapTy &TypeMap,
|
|||||||
// identical version of the symbol over in the dest module... the
|
// identical version of the symbol over in the dest module... the
|
||||||
// initializer will be filled in later by LinkGlobalInits.
|
// initializer will be filled in later by LinkGlobalInits.
|
||||||
GlobalVariable *NewDGV = new GlobalVariable(
|
GlobalVariable *NewDGV = new GlobalVariable(
|
||||||
*DstM, TypeMap.get(SGVar->getType()->getElementType()),
|
DstM, TypeMap.get(SGVar->getType()->getElementType()),
|
||||||
SGVar->isConstant(), getLinkage(SGVar), /*init*/ nullptr, getName(SGVar),
|
SGVar->isConstant(), getLinkage(SGVar), /*init*/ nullptr, getName(SGVar),
|
||||||
/*insertbefore*/ nullptr, SGVar->getThreadLocalMode(),
|
/*insertbefore*/ nullptr, SGVar->getThreadLocalMode(),
|
||||||
SGVar->getType()->getAddressSpace());
|
SGVar->getType()->getAddressSpace());
|
||||||
@ -808,7 +809,7 @@ Function *ModuleLinker::copyFunctionProto(TypeMapTy &TypeMap,
|
|||||||
// If there is no linkage to be performed or we are linking from the source,
|
// If there is no linkage to be performed or we are linking from the source,
|
||||||
// bring SF over.
|
// bring SF over.
|
||||||
return Function::Create(TypeMap.get(SF->getFunctionType()), getLinkage(SF),
|
return Function::Create(TypeMap.get(SF->getFunctionType()), getLinkage(SF),
|
||||||
getName(SF), DstM);
|
getName(SF), &DstM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set up prototypes for any aliases that come over from the source module.
|
/// Set up prototypes for any aliases that come over from the source module.
|
||||||
@ -842,7 +843,7 @@ GlobalValue *ModuleLinker::copyGlobalAliasProto(TypeMapTy &TypeMap,
|
|||||||
// bring over SGA.
|
// bring over SGA.
|
||||||
auto *Ty = TypeMap.get(SGA->getValueType());
|
auto *Ty = TypeMap.get(SGA->getValueType());
|
||||||
return GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(),
|
return GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(),
|
||||||
getLinkage(SGA), getName(SGA), DstM);
|
getLinkage(SGA), getName(SGA), &DstM);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GlobalValue::VisibilityTypes
|
static GlobalValue::VisibilityTypes
|
||||||
@ -936,9 +937,9 @@ void ModuleLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old) {
|
|||||||
linkGlobalValueBody(*Old);
|
linkGlobalValueBody(*Old);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleLinker::getComdatLeader(Module *M, StringRef ComdatName,
|
bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName,
|
||||||
const GlobalVariable *&GVar) {
|
const GlobalVariable *&GVar) {
|
||||||
const GlobalValue *GVal = M->getNamedValue(ComdatName);
|
const GlobalValue *GVal = M.getNamedValue(ComdatName);
|
||||||
if (const auto *GA = dyn_cast_or_null<GlobalAlias>(GVal)) {
|
if (const auto *GA = dyn_cast_or_null<GlobalAlias>(GVal)) {
|
||||||
GVal = GA->getBaseObject();
|
GVal = GA->getBaseObject();
|
||||||
if (!GVal)
|
if (!GVal)
|
||||||
@ -997,8 +998,8 @@ bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName,
|
|||||||
getComdatLeader(SrcM, ComdatName, SrcGV))
|
getComdatLeader(SrcM, ComdatName, SrcGV))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const DataLayout &DstDL = DstM->getDataLayout();
|
const DataLayout &DstDL = DstM.getDataLayout();
|
||||||
const DataLayout &SrcDL = SrcM->getDataLayout();
|
const DataLayout &SrcDL = SrcM.getDataLayout();
|
||||||
uint64_t DstSize =
|
uint64_t DstSize =
|
||||||
DstDL.getTypeAllocSize(DstGV->getType()->getPointerElementType());
|
DstDL.getTypeAllocSize(DstGV->getType()->getPointerElementType());
|
||||||
uint64_t SrcSize =
|
uint64_t SrcSize =
|
||||||
@ -1030,7 +1031,7 @@ bool ModuleLinker::getComdatResult(const Comdat *SrcC,
|
|||||||
bool &LinkFromSrc) {
|
bool &LinkFromSrc) {
|
||||||
Comdat::SelectionKind SSK = SrcC->getSelectionKind();
|
Comdat::SelectionKind SSK = SrcC->getSelectionKind();
|
||||||
StringRef ComdatName = SrcC->getName();
|
StringRef ComdatName = SrcC->getName();
|
||||||
Module::ComdatSymTabType &ComdatSymTab = DstM->getComdatSymbolTable();
|
Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable();
|
||||||
Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(ComdatName);
|
Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(ComdatName);
|
||||||
|
|
||||||
if (DstCI == ComdatSymTab.end()) {
|
if (DstCI == ComdatSymTab.end()) {
|
||||||
@ -1158,7 +1159,7 @@ bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
|
|||||||
/// types 'Foo' but one got renamed when the module was loaded into the same
|
/// types 'Foo' but one got renamed when the module was loaded into the same
|
||||||
/// LLVMContext.
|
/// LLVMContext.
|
||||||
void ModuleLinker::computeTypeMapping() {
|
void ModuleLinker::computeTypeMapping() {
|
||||||
for (GlobalValue &SGV : SrcM->globals()) {
|
for (GlobalValue &SGV : SrcM.globals()) {
|
||||||
GlobalValue *DGV = getLinkedToGlobal(&SGV);
|
GlobalValue *DGV = getLinkedToGlobal(&SGV);
|
||||||
if (!DGV)
|
if (!DGV)
|
||||||
continue;
|
continue;
|
||||||
@ -1174,12 +1175,12 @@ void ModuleLinker::computeTypeMapping() {
|
|||||||
TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType());
|
TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (GlobalValue &SGV : *SrcM) {
|
for (GlobalValue &SGV : SrcM) {
|
||||||
if (GlobalValue *DGV = getLinkedToGlobal(&SGV))
|
if (GlobalValue *DGV = getLinkedToGlobal(&SGV))
|
||||||
TypeMap.addTypeMapping(DGV->getType(), SGV.getType());
|
TypeMap.addTypeMapping(DGV->getType(), SGV.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (GlobalValue &SGV : SrcM->aliases()) {
|
for (GlobalValue &SGV : SrcM.aliases()) {
|
||||||
if (GlobalValue *DGV = getLinkedToGlobal(&SGV))
|
if (GlobalValue *DGV = getLinkedToGlobal(&SGV))
|
||||||
TypeMap.addTypeMapping(DGV->getType(), SGV.getType());
|
TypeMap.addTypeMapping(DGV->getType(), SGV.getType());
|
||||||
}
|
}
|
||||||
@ -1188,7 +1189,7 @@ void ModuleLinker::computeTypeMapping() {
|
|||||||
// At this point, the destination module may have a type "%foo = { i32 }" for
|
// At this point, the destination module may have a type "%foo = { i32 }" for
|
||||||
// example. When the source module got loaded into the same LLVMContext, if
|
// example. When the source module got loaded into the same LLVMContext, if
|
||||||
// it had the same type, it would have been renamed to "%foo.42 = { i32 }".
|
// it had the same type, it would have been renamed to "%foo.42 = { i32 }".
|
||||||
std::vector<StructType *> Types = SrcM->getIdentifiedStructTypes();
|
std::vector<StructType *> Types = SrcM.getIdentifiedStructTypes();
|
||||||
for (StructType *ST : Types) {
|
for (StructType *ST : Types) {
|
||||||
if (!ST->hasName())
|
if (!ST->hasName())
|
||||||
continue;
|
continue;
|
||||||
@ -1201,7 +1202,7 @@ void ModuleLinker::computeTypeMapping() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check to see if the destination module has a struct with the prefix name.
|
// Check to see if the destination module has a struct with the prefix name.
|
||||||
StructType *DST = DstM->getTypeByName(ST->getName().substr(0, DotPos));
|
StructType *DST = DstM.getTypeByName(ST->getName().substr(0, DotPos));
|
||||||
if (!DST)
|
if (!DST)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1275,10 +1276,10 @@ static void upgradeGlobalArray(GlobalVariable *GV) {
|
|||||||
|
|
||||||
void ModuleLinker::upgradeMismatchedGlobalArray(StringRef Name) {
|
void ModuleLinker::upgradeMismatchedGlobalArray(StringRef Name) {
|
||||||
// Look for the global arrays.
|
// Look for the global arrays.
|
||||||
auto *DstGV = dyn_cast_or_null<GlobalVariable>(DstM->getNamedValue(Name));
|
auto *DstGV = dyn_cast_or_null<GlobalVariable>(DstM.getNamedValue(Name));
|
||||||
if (!DstGV)
|
if (!DstGV)
|
||||||
return;
|
return;
|
||||||
auto *SrcGV = dyn_cast_or_null<GlobalVariable>(SrcM->getNamedValue(Name));
|
auto *SrcGV = dyn_cast_or_null<GlobalVariable>(SrcM.getNamedValue(Name));
|
||||||
if (!SrcGV)
|
if (!SrcGV)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1380,7 +1381,7 @@ bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
|
|||||||
|
|
||||||
// Create the new global variable.
|
// Create the new global variable.
|
||||||
GlobalVariable *NG = new GlobalVariable(
|
GlobalVariable *NG = new GlobalVariable(
|
||||||
*DstM, NewType, SrcGV->isConstant(), SrcGV->getLinkage(),
|
DstM, NewType, SrcGV->isConstant(), SrcGV->getLinkage(),
|
||||||
/*init*/ nullptr, /*name*/ "", DstGV, SrcGV->getThreadLocalMode(),
|
/*init*/ nullptr, /*name*/ "", DstGV, SrcGV->getThreadLocalMode(),
|
||||||
SrcGV->getType()->getAddressSpace());
|
SrcGV->getType()->getAddressSpace());
|
||||||
|
|
||||||
@ -1430,7 +1431,7 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {
|
|||||||
if (const Comdat *SC = SGV->getComdat()) {
|
if (const Comdat *SC = SGV->getComdat()) {
|
||||||
Comdat::SelectionKind SK;
|
Comdat::SelectionKind SK;
|
||||||
std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];
|
std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];
|
||||||
C = DstM->getOrInsertComdat(SC->getName());
|
C = DstM.getOrInsertComdat(SC->getName());
|
||||||
C->setSelectionKind(SK);
|
C->setSelectionKind(SK);
|
||||||
if (SGV->hasInternalLinkage())
|
if (SGV->hasInternalLinkage())
|
||||||
LinkFromSrc = true;
|
LinkFromSrc = true;
|
||||||
@ -1606,12 +1607,12 @@ bool ModuleLinker::linkGlobalValueBody(GlobalValue &Src) {
|
|||||||
|
|
||||||
/// Insert all of the named MDNodes in Src into the Dest module.
|
/// Insert all of the named MDNodes in Src into the Dest module.
|
||||||
void ModuleLinker::linkNamedMDNodes() {
|
void ModuleLinker::linkNamedMDNodes() {
|
||||||
const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata();
|
const NamedMDNode *SrcModFlags = SrcM.getModuleFlagsMetadata();
|
||||||
for (const NamedMDNode &NMD : SrcM->named_metadata()) {
|
for (const NamedMDNode &NMD : SrcM.named_metadata()) {
|
||||||
// Don't link module flags here. Do them separately.
|
// Don't link module flags here. Do them separately.
|
||||||
if (&NMD == SrcModFlags)
|
if (&NMD == SrcModFlags)
|
||||||
continue;
|
continue;
|
||||||
NamedMDNode *DestNMD = DstM->getOrInsertNamedMetadata(NMD.getName());
|
NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName());
|
||||||
// Add Src elements into Dest node.
|
// Add Src elements into Dest node.
|
||||||
for (const MDNode *op : NMD.operands())
|
for (const MDNode *op : NMD.operands())
|
||||||
DestNMD->addOperand(MapMetadata(
|
DestNMD->addOperand(MapMetadata(
|
||||||
@ -1623,12 +1624,12 @@ void ModuleLinker::linkNamedMDNodes() {
|
|||||||
/// Merge the linker flags in Src into the Dest module.
|
/// Merge the linker flags in Src into the Dest module.
|
||||||
bool ModuleLinker::linkModuleFlagsMetadata() {
|
bool ModuleLinker::linkModuleFlagsMetadata() {
|
||||||
// If the source module has no module flags, we are done.
|
// If the source module has no module flags, we are done.
|
||||||
const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata();
|
const NamedMDNode *SrcModFlags = SrcM.getModuleFlagsMetadata();
|
||||||
if (!SrcModFlags) return false;
|
if (!SrcModFlags) return false;
|
||||||
|
|
||||||
// If the destination module doesn't have module flags yet, then just copy
|
// If the destination module doesn't have module flags yet, then just copy
|
||||||
// over the source module's flags.
|
// over the source module's flags.
|
||||||
NamedMDNode *DstModFlags = DstM->getOrInsertModuleFlagsMetadata();
|
NamedMDNode *DstModFlags = DstM.getOrInsertModuleFlagsMetadata();
|
||||||
if (DstModFlags->getNumOperands() == 0) {
|
if (DstModFlags->getNumOperands() == 0) {
|
||||||
for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I)
|
for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I)
|
||||||
DstModFlags->addOperand(SrcModFlags->getOperand(I));
|
DstModFlags->addOperand(SrcModFlags->getOperand(I));
|
||||||
@ -1711,7 +1712,7 @@ bool ModuleLinker::linkModuleFlagsMetadata() {
|
|||||||
|
|
||||||
auto replaceDstValue = [&](MDNode *New) {
|
auto replaceDstValue = [&](MDNode *New) {
|
||||||
Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New};
|
Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New};
|
||||||
MDNode *Flag = MDNode::get(DstM->getContext(), FlagOps);
|
MDNode *Flag = MDNode::get(DstM.getContext(), FlagOps);
|
||||||
DstModFlags->setOperand(DstIndex, Flag);
|
DstModFlags->setOperand(DstIndex, Flag);
|
||||||
Flags[ID].first = Flag;
|
Flags[ID].first = Flag;
|
||||||
};
|
};
|
||||||
@ -1744,7 +1745,7 @@ bool ModuleLinker::linkModuleFlagsMetadata() {
|
|||||||
MDs.append(DstValue->op_begin(), DstValue->op_end());
|
MDs.append(DstValue->op_begin(), DstValue->op_end());
|
||||||
MDs.append(SrcValue->op_begin(), SrcValue->op_end());
|
MDs.append(SrcValue->op_begin(), SrcValue->op_end());
|
||||||
|
|
||||||
replaceDstValue(MDNode::get(DstM->getContext(), MDs));
|
replaceDstValue(MDNode::get(DstM.getContext(), MDs));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Module::AppendUnique: {
|
case Module::AppendUnique: {
|
||||||
@ -1754,7 +1755,7 @@ bool ModuleLinker::linkModuleFlagsMetadata() {
|
|||||||
Elts.insert(DstValue->op_begin(), DstValue->op_end());
|
Elts.insert(DstValue->op_begin(), DstValue->op_end());
|
||||||
Elts.insert(SrcValue->op_begin(), SrcValue->op_end());
|
Elts.insert(SrcValue->op_begin(), SrcValue->op_end());
|
||||||
|
|
||||||
replaceDstValue(MDNode::get(DstM->getContext(),
|
replaceDstValue(MDNode::get(DstM.getContext(),
|
||||||
makeArrayRef(Elts.begin(), Elts.end())));
|
makeArrayRef(Elts.begin(), Elts.end())));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1833,51 +1834,47 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleLinker::run() {
|
bool ModuleLinker::run() {
|
||||||
assert(DstM && "Null destination module");
|
|
||||||
assert(SrcM && "Null source module");
|
|
||||||
|
|
||||||
// Inherit the target data from the source module if the destination module
|
// Inherit the target data from the source module if the destination module
|
||||||
// doesn't have one already.
|
// doesn't have one already.
|
||||||
if (DstM->getDataLayout().isDefault())
|
if (DstM.getDataLayout().isDefault())
|
||||||
DstM->setDataLayout(SrcM->getDataLayout());
|
DstM.setDataLayout(SrcM.getDataLayout());
|
||||||
|
|
||||||
if (SrcM->getDataLayout() != DstM->getDataLayout()) {
|
if (SrcM.getDataLayout() != DstM.getDataLayout()) {
|
||||||
emitWarning("Linking two modules of different data layouts: '" +
|
emitWarning("Linking two modules of different data layouts: '" +
|
||||||
SrcM->getModuleIdentifier() + "' is '" +
|
SrcM.getModuleIdentifier() + "' is '" +
|
||||||
SrcM->getDataLayoutStr() + "' whereas '" +
|
SrcM.getDataLayoutStr() + "' whereas '" +
|
||||||
DstM->getModuleIdentifier() + "' is '" +
|
DstM.getModuleIdentifier() + "' is '" +
|
||||||
DstM->getDataLayoutStr() + "'\n");
|
DstM.getDataLayoutStr() + "'\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the target triple from the source to dest if the dest's is empty.
|
// Copy the target triple from the source to dest if the dest's is empty.
|
||||||
if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty())
|
if (DstM.getTargetTriple().empty() && !SrcM.getTargetTriple().empty())
|
||||||
DstM->setTargetTriple(SrcM->getTargetTriple());
|
DstM.setTargetTriple(SrcM.getTargetTriple());
|
||||||
|
|
||||||
Triple SrcTriple(SrcM->getTargetTriple()), DstTriple(DstM->getTargetTriple());
|
Triple SrcTriple(SrcM.getTargetTriple()), DstTriple(DstM.getTargetTriple());
|
||||||
|
|
||||||
if (!SrcM->getTargetTriple().empty() && !triplesMatch(SrcTriple, DstTriple))
|
if (!SrcM.getTargetTriple().empty() && !triplesMatch(SrcTriple, DstTriple))
|
||||||
emitWarning("Linking two modules of different target triples: " +
|
emitWarning("Linking two modules of different target triples: " +
|
||||||
SrcM->getModuleIdentifier() + "' is '" +
|
SrcM.getModuleIdentifier() + "' is '" + SrcM.getTargetTriple() +
|
||||||
SrcM->getTargetTriple() + "' whereas '" +
|
"' whereas '" + DstM.getModuleIdentifier() + "' is '" +
|
||||||
DstM->getModuleIdentifier() + "' is '" +
|
DstM.getTargetTriple() + "'\n");
|
||||||
DstM->getTargetTriple() + "'\n");
|
|
||||||
|
|
||||||
DstM->setTargetTriple(mergeTriples(SrcTriple, DstTriple));
|
DstM.setTargetTriple(mergeTriples(SrcTriple, DstTriple));
|
||||||
|
|
||||||
// Append the module inline asm string.
|
// Append the module inline asm string.
|
||||||
if (!SrcM->getModuleInlineAsm().empty()) {
|
if (!SrcM.getModuleInlineAsm().empty()) {
|
||||||
if (DstM->getModuleInlineAsm().empty())
|
if (DstM.getModuleInlineAsm().empty())
|
||||||
DstM->setModuleInlineAsm(SrcM->getModuleInlineAsm());
|
DstM.setModuleInlineAsm(SrcM.getModuleInlineAsm());
|
||||||
else
|
else
|
||||||
DstM->setModuleInlineAsm(DstM->getModuleInlineAsm()+"\n"+
|
DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" +
|
||||||
SrcM->getModuleInlineAsm());
|
SrcM.getModuleInlineAsm());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop over all of the linked values to compute type mappings.
|
// Loop over all of the linked values to compute type mappings.
|
||||||
computeTypeMapping();
|
computeTypeMapping();
|
||||||
|
|
||||||
ComdatsChosen.clear();
|
ComdatsChosen.clear();
|
||||||
for (const auto &SMEC : SrcM->getComdatSymbolTable()) {
|
for (const auto &SMEC : SrcM.getComdatSymbolTable()) {
|
||||||
const Comdat &C = SMEC.getValue();
|
const Comdat &C = SMEC.getValue();
|
||||||
if (ComdatsChosen.count(&C))
|
if (ComdatsChosen.count(&C))
|
||||||
continue;
|
continue;
|
||||||
@ -1891,37 +1888,37 @@ bool ModuleLinker::run() {
|
|||||||
// Upgrade mismatched global arrays.
|
// Upgrade mismatched global arrays.
|
||||||
upgradeMismatchedGlobals();
|
upgradeMismatchedGlobals();
|
||||||
|
|
||||||
for (GlobalVariable &GV : SrcM->globals())
|
for (GlobalVariable &GV : SrcM.globals())
|
||||||
if (const Comdat *SC = GV.getComdat())
|
if (const Comdat *SC = GV.getComdat())
|
||||||
ComdatMembers[SC].push_back(&GV);
|
ComdatMembers[SC].push_back(&GV);
|
||||||
|
|
||||||
for (Function &SF : *SrcM)
|
for (Function &SF : SrcM)
|
||||||
if (const Comdat *SC = SF.getComdat())
|
if (const Comdat *SC = SF.getComdat())
|
||||||
ComdatMembers[SC].push_back(&SF);
|
ComdatMembers[SC].push_back(&SF);
|
||||||
|
|
||||||
for (GlobalAlias &GA : SrcM->aliases())
|
for (GlobalAlias &GA : SrcM.aliases())
|
||||||
if (const Comdat *SC = GA.getComdat())
|
if (const Comdat *SC = GA.getComdat())
|
||||||
ComdatMembers[SC].push_back(&GA);
|
ComdatMembers[SC].push_back(&GA);
|
||||||
|
|
||||||
// Insert all of the globals in src into the DstM module... without linking
|
// Insert all of the globals in src into the DstM module... without linking
|
||||||
// initializers (which could refer to functions not yet mapped over).
|
// initializers (which could refer to functions not yet mapped over).
|
||||||
for (GlobalVariable &GV : SrcM->globals())
|
for (GlobalVariable &GV : SrcM.globals())
|
||||||
if (linkIfNeeded(GV))
|
if (linkIfNeeded(GV))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (Function &SF : *SrcM)
|
for (Function &SF : SrcM)
|
||||||
if (linkIfNeeded(SF))
|
if (linkIfNeeded(SF))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (GlobalAlias &GA : SrcM->aliases())
|
for (GlobalAlias &GA : SrcM.aliases())
|
||||||
if (linkIfNeeded(GA))
|
if (linkIfNeeded(GA))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (const auto &Entry : DstM->getComdatSymbolTable()) {
|
for (const auto &Entry : DstM.getComdatSymbolTable()) {
|
||||||
const Comdat &C = Entry.getValue();
|
const Comdat &C = Entry.getValue();
|
||||||
if (C.getSelectionKind() == Comdat::Any)
|
if (C.getSelectionKind() == Comdat::Any)
|
||||||
continue;
|
continue;
|
||||||
const GlobalValue *GV = SrcM->getNamedValue(C.getName());
|
const GlobalValue *GV = SrcM.getNamedValue(C.getName());
|
||||||
if (GV)
|
if (GV)
|
||||||
MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer);
|
MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer);
|
||||||
}
|
}
|
||||||
@ -2032,12 +2029,10 @@ bool Linker::IdentifiedStructTypeSet::hasType(StructType *Ty) {
|
|||||||
return *I == Ty;
|
return *I == Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Linker::Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler) {
|
Linker::Linker(Module &M, DiagnosticHandlerFunction DiagnosticHandler)
|
||||||
this->Composite = M;
|
: Composite(M), DiagnosticHandler(DiagnosticHandler) {
|
||||||
this->DiagnosticHandler = DiagnosticHandler;
|
|
||||||
|
|
||||||
TypeFinder StructTypes;
|
TypeFinder StructTypes;
|
||||||
StructTypes.run(*M, true);
|
StructTypes.run(M, true);
|
||||||
for (StructType *Ty : StructTypes) {
|
for (StructType *Ty : StructTypes) {
|
||||||
if (Ty->isOpaque())
|
if (Ty->isOpaque())
|
||||||
IdentifiedStructTypes.addOpaque(Ty);
|
IdentifiedStructTypes.addOpaque(Ty);
|
||||||
@ -2046,18 +2041,18 @@ Linker::Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Linker::Linker(Module *M)
|
Linker::Linker(Module &M)
|
||||||
: Linker(M, [this](const DiagnosticInfo &DI) {
|
: Linker(M, [this](const DiagnosticInfo &DI) {
|
||||||
Composite->getContext().diagnose(DI);
|
Composite.getContext().diagnose(DI);
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
bool Linker::linkInModule(Module *Src, unsigned Flags,
|
bool Linker::linkInModule(Module &Src, unsigned Flags,
|
||||||
const FunctionInfoIndex *Index,
|
const FunctionInfoIndex *Index,
|
||||||
Function *FuncToImport) {
|
Function *FuncToImport) {
|
||||||
ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src,
|
ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src,
|
||||||
DiagnosticHandler, Flags, Index, FuncToImport);
|
DiagnosticHandler, Flags, Index, FuncToImport);
|
||||||
bool RetCode = TheLinker.run();
|
bool RetCode = TheLinker.run();
|
||||||
Composite->dropTriviallyDeadConstantArrays();
|
Composite.dropTriviallyDeadConstantArrays();
|
||||||
return RetCode;
|
return RetCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2070,14 +2065,14 @@ bool Linker::linkInModule(Module *Src, unsigned Flags,
|
|||||||
/// true is returned and ErrorMsg (if not null) is set to indicate the problem.
|
/// 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
|
/// Upon failure, the Dest module could be in a modified state, and shouldn't be
|
||||||
/// relied on to be consistent.
|
/// relied on to be consistent.
|
||||||
bool Linker::LinkModules(Module *Dest, Module *Src,
|
bool Linker::linkModules(Module &Dest, Module &Src,
|
||||||
DiagnosticHandlerFunction DiagnosticHandler,
|
DiagnosticHandlerFunction DiagnosticHandler,
|
||||||
unsigned Flags) {
|
unsigned Flags) {
|
||||||
Linker L(Dest, DiagnosticHandler);
|
Linker L(Dest, DiagnosticHandler);
|
||||||
return L.linkInModule(Src, Flags);
|
return L.linkInModule(Src, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Flags) {
|
bool Linker::linkModules(Module &Dest, Module &Src, unsigned Flags) {
|
||||||
Linker L(Dest);
|
Linker L(Dest);
|
||||||
return L.linkInModule(Src, Flags);
|
return L.linkInModule(Src, Flags);
|
||||||
}
|
}
|
||||||
@ -2093,8 +2088,8 @@ LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src,
|
|||||||
raw_string_ostream Stream(Message);
|
raw_string_ostream Stream(Message);
|
||||||
DiagnosticPrinterRawOStream DP(Stream);
|
DiagnosticPrinterRawOStream DP(Stream);
|
||||||
|
|
||||||
LLVMBool Result = Linker::LinkModules(
|
LLVMBool Result = Linker::linkModules(
|
||||||
D, unwrap(Src), [&](const DiagnosticInfo &DI) { DI.print(DP); });
|
*D, *unwrap(Src), [&](const DiagnosticInfo &DI) { DI.print(DP); });
|
||||||
|
|
||||||
if (OutMessages && Result) {
|
if (OutMessages && Result) {
|
||||||
Stream.flush();
|
Stream.flush();
|
||||||
|
@ -102,7 +102,7 @@ bool FunctionImporter::importFunctions(Module &M) {
|
|||||||
/// Second step: for every call to an external function, try to import it.
|
/// Second step: for every call to an external function, try to import it.
|
||||||
|
|
||||||
// Linker that will be used for importing function
|
// Linker that will be used for importing function
|
||||||
Linker L(&M, DiagnosticHandler);
|
Linker L(M, DiagnosticHandler);
|
||||||
|
|
||||||
while (!Worklist.empty()) {
|
while (!Worklist.empty()) {
|
||||||
auto CalledFunctionName = Worklist.pop_back_val();
|
auto CalledFunctionName = Worklist.pop_back_val();
|
||||||
@ -182,7 +182,7 @@ bool FunctionImporter::importFunctions(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Link in the specified function.
|
// Link in the specified function.
|
||||||
if (L.linkInModule(&Module, Linker::Flags::None, &Index, F))
|
if (L.linkInModule(Module, Linker::Flags::None, &Index, F))
|
||||||
report_fatal_error("Function Import: link error");
|
report_fatal_error("Function Import: link error");
|
||||||
|
|
||||||
// Process the newly imported function and add callees to the worklist.
|
// Process the newly imported function and add callees to the worklist.
|
||||||
|
@ -132,7 +132,7 @@ bool BugDriver::addSources(const std::vector<std::string> &Filenames) {
|
|||||||
if (!M.get()) return true;
|
if (!M.get()) return true;
|
||||||
|
|
||||||
outs() << "Linking in input file: '" << Filenames[i] << "'\n";
|
outs() << "Linking in input file: '" << Filenames[i] << "'\n";
|
||||||
if (Linker::LinkModules(Program, M.get()))
|
if (Linker::linkModules(*Program, *M))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ static Module *TestMergedProgram(const BugDriver &BD, Module *M1, Module *M2,
|
|||||||
M1 = CloneModule(M1);
|
M1 = CloneModule(M1);
|
||||||
M2 = CloneModule(M2);
|
M2 = CloneModule(M2);
|
||||||
}
|
}
|
||||||
if (Linker::LinkModules(M1, M2))
|
if (Linker::linkModules(*M1, *M2))
|
||||||
exit(1);
|
exit(1);
|
||||||
delete M2; // We are done with this module.
|
delete M2; // We are done with this module.
|
||||||
|
|
||||||
@ -390,7 +390,7 @@ static bool ExtractLoops(BugDriver &BD,
|
|||||||
MisCompFunctions.emplace_back(F->getName(), F->getFunctionType());
|
MisCompFunctions.emplace_back(F->getName(), F->getFunctionType());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted))
|
if (Linker::linkModules(*ToNotOptimize, *ToOptimizeLoopExtracted))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
MiscompiledFunctions.clear();
|
MiscompiledFunctions.clear();
|
||||||
@ -418,7 +418,7 @@ static bool ExtractLoops(BugDriver &BD,
|
|||||||
// extraction both didn't break the program, and didn't mask the problem.
|
// extraction both didn't break the program, and didn't mask the problem.
|
||||||
// Replace the current program with the loop extracted version, and try to
|
// Replace the current program with the loop extracted version, and try to
|
||||||
// extract another loop.
|
// extract another loop.
|
||||||
if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted))
|
if (Linker::linkModules(*ToNotOptimize, *ToOptimizeLoopExtracted))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
delete ToOptimizeLoopExtracted;
|
delete ToOptimizeLoopExtracted;
|
||||||
@ -594,7 +594,7 @@ static bool ExtractBlocks(BugDriver &BD,
|
|||||||
if (!I->isDeclaration())
|
if (!I->isDeclaration())
|
||||||
MisCompFunctions.emplace_back(I->getName(), I->getFunctionType());
|
MisCompFunctions.emplace_back(I->getName(), I->getFunctionType());
|
||||||
|
|
||||||
if (Linker::LinkModules(ProgClone, Extracted.get()))
|
if (Linker::linkModules(*ProgClone, *Extracted))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
// Set the new program and delete the old one.
|
// Set the new program and delete the old one.
|
||||||
|
@ -938,7 +938,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
|
std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
|
||||||
Linker L(Combined.get());
|
Linker L(*Combined);
|
||||||
|
|
||||||
std::string DefaultTriple = sys::getDefaultTargetTriple();
|
std::string DefaultTriple = sys::getDefaultTargetTriple();
|
||||||
|
|
||||||
@ -956,7 +956,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
|
|||||||
M->setTargetTriple(DefaultTriple);
|
M->setTargetTriple(DefaultTriple);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (L.linkInModule(M.get()))
|
if (L.linkInModule(*M))
|
||||||
message(LDPL_FATAL, "Failed to link module");
|
message(LDPL_FATAL, "Failed to link module");
|
||||||
if (release_input_file(F.handle) != LDPS_OK)
|
if (release_input_file(F.handle) != LDPS_OK)
|
||||||
message(LDPL_FATAL, "Failed to release file information");
|
message(LDPL_FATAL, "Failed to release file information");
|
||||||
@ -986,7 +986,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
|
|||||||
path = output_name;
|
path = output_name;
|
||||||
else
|
else
|
||||||
path = output_name + ".bc";
|
path = output_name + ".bc";
|
||||||
saveBCFile(path, *L.getModule());
|
saveBCFile(path, *Combined);
|
||||||
if (options::TheOutputType == options::OT_BC_ONLY)
|
if (options::TheOutputType == options::OT_BC_ONLY)
|
||||||
return LDPS_OK;
|
return LDPS_OK;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ static bool importFunctions(const char *argv0, LLVMContext &Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Link in the specified function.
|
// Link in the specified function.
|
||||||
if (L.linkInModule(M.get(), Linker::Flags::None, Index.get(), F))
|
if (L.linkInModule(*M, Linker::Flags::None, Index.get(), F))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -238,7 +238,7 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
|
|||||||
if (Verbose)
|
if (Verbose)
|
||||||
errs() << "Linking in '" << File << "'\n";
|
errs() << "Linking in '" << File << "'\n";
|
||||||
|
|
||||||
if (L.linkInModule(M.get(), ApplicableFlags, Index.get()))
|
if (L.linkInModule(*M, ApplicableFlags, Index.get()))
|
||||||
return false;
|
return false;
|
||||||
// All linker flags apply to linking of subsequent files.
|
// All linker flags apply to linking of subsequent files.
|
||||||
ApplicableFlags = Flags;
|
ApplicableFlags = Flags;
|
||||||
@ -266,7 +266,7 @@ int main(int argc, char **argv) {
|
|||||||
cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
|
cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
|
||||||
|
|
||||||
auto Composite = make_unique<Module>("llvm-link", Context);
|
auto Composite = make_unique<Module>("llvm-link", Context);
|
||||||
Linker L(Composite.get(), diagnosticHandler);
|
Linker L(*Composite, diagnosticHandler);
|
||||||
|
|
||||||
unsigned Flags = Linker::Flags::None;
|
unsigned Flags = Linker::Flags::None;
|
||||||
if (Internalize)
|
if (Internalize)
|
||||||
|
@ -93,7 +93,7 @@ TEST_F(LinkModuleTest, BlockAddress) {
|
|||||||
Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx)));
|
Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx)));
|
||||||
|
|
||||||
Module *LinkedModule = new Module("MyModuleLinked", Ctx);
|
Module *LinkedModule = new Module("MyModuleLinked", Ctx);
|
||||||
Linker::LinkModules(LinkedModule, M.get());
|
Linker::linkModules(*LinkedModule, *M);
|
||||||
|
|
||||||
// Delete the original module.
|
// Delete the original module.
|
||||||
M.reset();
|
M.reset();
|
||||||
@ -169,13 +169,13 @@ static Module *getInternal(LLVMContext &Ctx) {
|
|||||||
TEST_F(LinkModuleTest, EmptyModule) {
|
TEST_F(LinkModuleTest, EmptyModule) {
|
||||||
std::unique_ptr<Module> InternalM(getInternal(Ctx));
|
std::unique_ptr<Module> InternalM(getInternal(Ctx));
|
||||||
std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
|
std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
|
||||||
Linker::LinkModules(EmptyM.get(), InternalM.get());
|
Linker::linkModules(*EmptyM, *InternalM);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LinkModuleTest, EmptyModule2) {
|
TEST_F(LinkModuleTest, EmptyModule2) {
|
||||||
std::unique_ptr<Module> InternalM(getInternal(Ctx));
|
std::unique_ptr<Module> InternalM(getInternal(Ctx));
|
||||||
std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
|
std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
|
||||||
Linker::LinkModules(InternalM.get(), EmptyM.get());
|
Linker::linkModules(*InternalM, *EmptyM);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LinkModuleTest, TypeMerge) {
|
TEST_F(LinkModuleTest, TypeMerge) {
|
||||||
@ -190,7 +190,7 @@ TEST_F(LinkModuleTest, TypeMerge) {
|
|||||||
"@t2 = weak global %t zeroinitializer\n";
|
"@t2 = weak global %t zeroinitializer\n";
|
||||||
std::unique_ptr<Module> M2 = parseAssemblyString(M2Str, Err, C);
|
std::unique_ptr<Module> M2 = parseAssemblyString(M2Str, Err, C);
|
||||||
|
|
||||||
Linker::LinkModules(M1.get(), M2.get(), [](const llvm::DiagnosticInfo &){});
|
Linker::linkModules(*M1, *M2, [](const llvm::DiagnosticInfo &) {});
|
||||||
|
|
||||||
EXPECT_EQ(M1->getNamedGlobal("t1")->getType(),
|
EXPECT_EQ(M1->getNamedGlobal("t1")->getType(),
|
||||||
M1->getNamedGlobal("t2")->getType());
|
M1->getNamedGlobal("t2")->getType());
|
||||||
@ -267,8 +267,7 @@ TEST_F(LinkModuleTest, MoveDistinctMDs) {
|
|||||||
// Link into destination module.
|
// Link into destination module.
|
||||||
auto Dst = llvm::make_unique<Module>("Linked", C);
|
auto Dst = llvm::make_unique<Module>("Linked", C);
|
||||||
ASSERT_TRUE(Dst.get());
|
ASSERT_TRUE(Dst.get());
|
||||||
Linker::LinkModules(Dst.get(), Src.get(),
|
Linker::linkModules(*Dst, *Src, [](const llvm::DiagnosticInfo &) {});
|
||||||
[](const llvm::DiagnosticInfo &) {});
|
|
||||||
|
|
||||||
// Check that distinct metadata was moved, not cloned. Even !4, the uniqued
|
// Check that distinct metadata was moved, not cloned. Even !4, the uniqued
|
||||||
// node, should effectively be moved, since its only operand hasn't changed.
|
// node, should effectively be moved, since its only operand hasn't changed.
|
||||||
|
Loading…
Reference in New Issue
Block a user