diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 21:25:48 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 21:25:48 +0000 |
commit | d88c1a5a572cdb661c111098831fa526e933756f (patch) | |
tree | 97b32c3372106ac47ded3d1a99f9c023a8530073 /contrib/llvm/lib/Linker | |
parent | 715652a404ee99f10c09c0a5edbb5883961b8c25 (diff) | |
parent | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (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.cpp | 138 | ||||
-rw-r--r-- | contrib/llvm/lib/Linker/LinkModules.cpp | 4 |
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; |