aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Linker
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 21:25:48 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 21:25:48 +0000
commitd88c1a5a572cdb661c111098831fa526e933756f (patch)
tree97b32c3372106ac47ded3d1a99f9c023a8530073 /contrib/llvm/lib/Linker
parent715652a404ee99f10c09c0a5edbb5883961b8c25 (diff)
parentb915e9e0fc85ba6f398b3fab0db6a81a8913af94 (diff)
Update llvm to trunk r290819 and resolve conflicts.
Notes
Notes: svn path=/projects/clang400-import/; revision=311142
Diffstat (limited to 'contrib/llvm/lib/Linker')
-rw-r--r--contrib/llvm/lib/Linker/IRMover.cpp138
-rw-r--r--contrib/llvm/lib/Linker/LinkModules.cpp4
2 files changed, 110 insertions, 32 deletions
diff --git a/contrib/llvm/lib/Linker/IRMover.cpp b/contrib/llvm/lib/Linker/IRMover.cpp
index 09c67bc47863..9f3cfc0eace4 100644
--- a/contrib/llvm/lib/Linker/IRMover.cpp
+++ b/contrib/llvm/lib/Linker/IRMover.cpp
@@ -169,11 +169,9 @@ bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) {
if (DSTy->isLiteral() != SSTy->isLiteral() ||
DSTy->isPacked() != SSTy->isPacked())
return false;
- } else if (ArrayType *DATy = dyn_cast<ArrayType>(DstTy)) {
- if (DATy->getNumElements() != cast<ArrayType>(SrcTy)->getNumElements())
- return false;
- } else if (VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- if (DVTy->getNumElements() != cast<VectorType>(SrcTy)->getNumElements())
+ } else if (auto *DSeqTy = dyn_cast<SequentialType>(DstTy)) {
+ if (DSeqTy->getNumElements() !=
+ cast<SequentialType>(SrcTy)->getNumElements())
return false;
}
@@ -281,7 +279,7 @@ Type *TypeMapTy::get(Type *Ty, SmallPtrSet<StructType *, 8> &Visited) {
}
// If all of the element types mapped directly over and the type is not
- // a nomed struct, then the type is usable as-is.
+ // a named struct, then the type is usable as-is.
if (!AnyChange && IsUniqued)
return *Entry = Ty;
@@ -397,6 +395,12 @@ class IRLinker {
Worklist.push_back(GV);
}
+ /// Flag whether the ModuleInlineAsm string in Src should be linked with
+ /// (concatenated into) the ModuleInlineAsm string for the destination
+ /// module. It should be true for full LTO, but not when importing for
+ /// ThinLTO, otherwise we can have duplicate symbols.
+ bool LinkModuleInlineAsm;
+
/// Set to true when all global value body linking is complete (including
/// lazy linking). Used to prevent metadata linking from creating new
/// references.
@@ -465,7 +469,7 @@ class IRLinker {
Error linkModuleFlagsMetadata();
- void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src);
+ void linkGlobalVariable(GlobalVariable &Dst, GlobalVariable &Src);
Error linkFunctionBody(Function &Dst, Function &Src);
void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src);
Error linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src);
@@ -476,16 +480,21 @@ class IRLinker {
Function *copyFunctionProto(const Function *SF);
GlobalValue *copyGlobalAliasProto(const GlobalAlias *SGA);
+ /// When importing for ThinLTO, prevent importing of types listed on
+ /// the DICompileUnit that we don't need a copy of in the importing
+ /// module.
+ void prepareCompileUnitsForImport();
void linkNamedMDNodes();
public:
IRLinker(Module &DstM, MDMapT &SharedMDs,
IRMover::IdentifiedStructTypeSet &Set, std::unique_ptr<Module> SrcM,
ArrayRef<GlobalValue *> ValuesToLink,
- std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor)
+ std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor,
+ bool LinkModuleInlineAsm, bool IsPerformingImport)
: DstM(DstM), SrcM(std::move(SrcM)), AddLazyFor(std::move(AddLazyFor)),
TypeMap(Set), GValMaterializer(*this), LValMaterializer(*this),
- SharedMDs(SharedMDs),
+ SharedMDs(SharedMDs), LinkModuleInlineAsm(LinkModuleInlineAsm),
Mapper(ValueMap, RF_MoveDistinctMDs | RF_IgnoreMissingLocals, &TypeMap,
&GValMaterializer),
AliasMCID(Mapper.registerAlternateMappingContext(AliasValueMap,
@@ -493,6 +502,8 @@ public:
ValueMap.getMDMap() = std::move(SharedMDs);
for (GlobalValue *GV : ValuesToLink)
maybeAdd(GV);
+ if (IsPerformingImport)
+ prepareCompileUnitsForImport();
}
~IRLinker() { SharedMDs = std::move(*ValueMap.getMDMap()); }
@@ -561,7 +572,7 @@ Value *IRLinker::materialize(Value *V, bool ForAlias) {
}
// When linking a global for an alias, it will always be linked. However we
- // need to check if it was not already scheduled to satify a reference from a
+ // need to check if it was not already scheduled to satisfy a reference from a
// regular global value initializer. We know if it has been schedule if the
// "New" GlobalValue that is mapped here for the alias is the same as the one
// already mapped. If there is an entry in the ValueMap but the value is
@@ -813,18 +824,17 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
SmallVector<Constant *, 16> SrcElements;
getArrayElements(SrcGV->getInitializer(), SrcElements);
- if (IsNewStructor)
- SrcElements.erase(
- std::remove_if(SrcElements.begin(), SrcElements.end(),
- [this](Constant *E) {
- auto *Key = dyn_cast<GlobalValue>(
- E->getAggregateElement(2)->stripPointerCasts());
- if (!Key)
- return false;
- GlobalValue *DGV = getLinkedToGlobal(Key);
- return !shouldLink(DGV, *Key);
- }),
- SrcElements.end());
+ if (IsNewStructor) {
+ auto It = remove_if(SrcElements, [this](Constant *E) {
+ auto *Key =
+ dyn_cast<GlobalValue>(E->getAggregateElement(2)->stripPointerCasts());
+ if (!Key)
+ return false;
+ GlobalValue *DGV = getLinkedToGlobal(Key);
+ return !shouldLink(DGV, *Key);
+ });
+ SrcElements.erase(It, SrcElements.end());
+ }
uint64_t NewSize = DstNumElements + SrcElements.size();
ArrayType *NewType = ArrayType::get(EltTy, NewSize);
@@ -951,7 +961,7 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
/// Update the initializers in the Dest module now that all globals that may be
/// referenced are in Dest.
-void IRLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) {
+void IRLinker::linkGlobalVariable(GlobalVariable &Dst, GlobalVariable &Src) {
// Figure out what the initializer looks like in the dest module.
Mapper.scheduleMapGlobalInitializer(Dst, *Src.getInitializer());
}
@@ -963,8 +973,8 @@ Error IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
assert(Dst.isDeclaration() && !Src.isDeclaration());
// Materialize if needed.
- if (std::error_code EC = Src.materialize())
- return errorCodeToError(EC);
+ if (Error Err = Src.materialize())
+ return Err;
// Link in the operands without remapping.
if (Src.hasPrefixData())
@@ -994,13 +1004,77 @@ Error IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
if (auto *F = dyn_cast<Function>(&Src))
return linkFunctionBody(cast<Function>(Dst), *F);
if (auto *GVar = dyn_cast<GlobalVariable>(&Src)) {
- linkGlobalInit(cast<GlobalVariable>(Dst), *GVar);
+ linkGlobalVariable(cast<GlobalVariable>(Dst), *GVar);
return Error::success();
}
linkAliasBody(cast<GlobalAlias>(Dst), cast<GlobalAlias>(Src));
return Error::success();
}
+void IRLinker::prepareCompileUnitsForImport() {
+ NamedMDNode *SrcCompileUnits = SrcM->getNamedMetadata("llvm.dbg.cu");
+ if (!SrcCompileUnits)
+ return;
+ // When importing for ThinLTO, prevent importing of types listed on
+ // the DICompileUnit that we don't need a copy of in the importing
+ // module. They will be emitted by the originating module.
+ for (unsigned I = 0, E = SrcCompileUnits->getNumOperands(); I != E; ++I) {
+ auto *CU = cast<DICompileUnit>(SrcCompileUnits->getOperand(I));
+ assert(CU && "Expected valid compile unit");
+ // Enums, macros, and retained types don't need to be listed on the
+ // imported DICompileUnit. This means they will only be imported
+ // if reached from the mapped IR. Do this by setting their value map
+ // entries to nullptr, which will automatically prevent their importing
+ // when reached from the DICompileUnit during metadata mapping.
+ ValueMap.MD()[CU->getRawEnumTypes()].reset(nullptr);
+ ValueMap.MD()[CU->getRawMacros()].reset(nullptr);
+ ValueMap.MD()[CU->getRawRetainedTypes()].reset(nullptr);
+ // If we ever start importing global variable defs, we'll need to
+ // add their DIGlobalVariable to the globals list on the imported
+ // DICompileUnit. Confirm none are imported, and then we can
+ // map the list of global variables to nullptr.
+ assert(none_of(
+ ValuesToLink,
+ [](const GlobalValue *GV) { return isa<GlobalVariable>(GV); }) &&
+ "Unexpected importing of a GlobalVariable definition");
+ ValueMap.MD()[CU->getRawGlobalVariables()].reset(nullptr);
+
+ // Imported entities only need to be mapped in if they have local
+ // scope, as those might correspond to an imported entity inside a
+ // function being imported (any locally scoped imported entities that
+ // don't end up referenced by an imported function will not be emitted
+ // into the object). Imported entities not in a local scope
+ // (e.g. on the namespace) only need to be emitted by the originating
+ // module. Create a list of the locally scoped imported entities, and
+ // replace the source CUs imported entity list with the new list, so
+ // only those are mapped in.
+ // FIXME: Locally-scoped imported entities could be moved to the
+ // functions they are local to instead of listing them on the CU, and
+ // we would naturally only link in those needed by function importing.
+ SmallVector<TrackingMDNodeRef, 4> AllImportedModules;
+ bool ReplaceImportedEntities = false;
+ for (auto *IE : CU->getImportedEntities()) {
+ DIScope *Scope = IE->getScope();
+ assert(Scope && "Invalid Scope encoding!");
+ if (isa<DILocalScope>(Scope))
+ AllImportedModules.emplace_back(IE);
+ else
+ ReplaceImportedEntities = true;
+ }
+ if (ReplaceImportedEntities) {
+ if (!AllImportedModules.empty())
+ CU->replaceImportedEntities(MDTuple::get(
+ CU->getContext(),
+ SmallVector<Metadata *, 16>(AllImportedModules.begin(),
+ AllImportedModules.end())));
+ else
+ // If there were no local scope imported entities, we can map
+ // the whole list to nullptr.
+ ValueMap.MD()[CU->getRawImportedEntities()].reset(nullptr);
+ }
+ }
+}
+
/// Insert all of the named MDNodes in Src into the Dest module.
void IRLinker::linkNamedMDNodes() {
const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata();
@@ -1191,8 +1265,8 @@ static std::string mergeTriples(const Triple &SrcTriple,
Error IRLinker::run() {
// Ensure metadata materialized before value mapping.
if (SrcM->getMaterializer())
- if (std::error_code EC = SrcM->getMaterializer()->materializeMetadata())
- return errorCodeToError(EC);
+ if (Error Err = SrcM->getMaterializer()->materializeMetadata())
+ return Err;
// Inherit the target data from the source module if the destination module
// doesn't have one already.
@@ -1223,7 +1297,7 @@ Error IRLinker::run() {
DstM.setTargetTriple(mergeTriples(SrcTriple, DstTriple));
// Append the module inline asm string.
- if (!SrcM->getModuleInlineAsm().empty()) {
+ if (LinkModuleInlineAsm && !SrcM->getModuleInlineAsm().empty()) {
if (DstM.getModuleInlineAsm().empty())
DstM.setModuleInlineAsm(SrcM->getModuleInlineAsm());
else
@@ -1361,9 +1435,11 @@ IRMover::IRMover(Module &M) : Composite(M) {
Error IRMover::move(
std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
- std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor) {
+ std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor,
+ bool LinkModuleInlineAsm, bool IsPerformingImport) {
IRLinker TheIRLinker(Composite, SharedMDs, IdentifiedStructTypes,
- std::move(Src), ValuesToLink, std::move(AddLazyFor));
+ std::move(Src), ValuesToLink, std::move(AddLazyFor),
+ LinkModuleInlineAsm, IsPerformingImport);
Error E = TheIRLinker.run();
Composite.dropTriviallyDeadConstantArrays();
return E;
diff --git a/contrib/llvm/lib/Linker/LinkModules.cpp b/contrib/llvm/lib/Linker/LinkModules.cpp
index fae9c95ebe8f..cf2c4ccf523e 100644
--- a/contrib/llvm/lib/Linker/LinkModules.cpp
+++ b/contrib/llvm/lib/Linker/LinkModules.cpp
@@ -582,7 +582,9 @@ bool ModuleLinker::run() {
if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(),
[this](GlobalValue &GV, IRMover::ValueAdder Add) {
addLazyFor(GV, Add);
- })) {
+ },
+ /* LinkModuleInlineAsm */ !isPerformingImport(),
+ /* IsPerformingImport */ isPerformingImport())) {
handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message()));
HasErrors = true;