diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-02-15 14:58:40 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-02-15 14:58:40 +0000 |
commit | 13138422bc354a1ec35f53a27c4efeccdffc5639 (patch) | |
tree | 8948a8a0aadc77afefcbe0f84abe732eece4aaa0 /contrib/llvm-project/llvm/lib/ExecutionEngine/Orc | |
parent | c246b3930d394722a836a9e724bd5ffba7c4a9b7 (diff) | |
parent | d75c7debad4509ece98792074e64b8a650a27bdb (diff) |
Notes
Diffstat (limited to 'contrib/llvm-project/llvm/lib/ExecutionEngine/Orc')
8 files changed, 193 insertions, 79 deletions
diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp index f26835ff8a08..9c504da611e0 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp @@ -67,9 +67,11 @@ namespace orc { class PartitioningIRMaterializationUnit : public IRMaterializationUnit { public: - PartitioningIRMaterializationUnit(ExecutionSession &ES, ThreadSafeModule TSM, - VModuleKey K, CompileOnDemandLayer &Parent) - : IRMaterializationUnit(ES, std::move(TSM), std::move(K)), + PartitioningIRMaterializationUnit(ExecutionSession &ES, + const ManglingOptions &MO, + ThreadSafeModule TSM, VModuleKey K, + CompileOnDemandLayer &Parent) + : IRMaterializationUnit(ES, MO, std::move(TSM), std::move(K)), Parent(Parent) {} PartitioningIRMaterializationUnit( @@ -111,7 +113,8 @@ CompileOnDemandLayer::compileWholeModule(GlobalValueSet Requested) { CompileOnDemandLayer::CompileOnDemandLayer( ExecutionSession &ES, IRLayer &BaseLayer, LazyCallThroughManager &LCTMgr, IndirectStubsManagerBuilder BuildIndirectStubsManager) - : IRLayer(ES), BaseLayer(BaseLayer), LCTMgr(LCTMgr), + : IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer), + LCTMgr(LCTMgr), BuildIndirectStubsManager(std::move(BuildIndirectStubsManager)) {} void CompileOnDemandLayer::setPartitionFunction(PartitionFunction Partition) { @@ -136,27 +139,23 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R, TSM.withModuleDo([&](Module &M) { // First, do some cleanup on the module: cleanUpModule(M); - - MangleAndInterner Mangle(ES, M.getDataLayout()); - for (auto &GV : M.global_values()) { - if (GV.isDeclaration() || GV.hasLocalLinkage() || - GV.hasAppendingLinkage()) - continue; - - auto Name = Mangle(GV.getName()); - auto Flags = JITSymbolFlags::fromGlobalValue(GV); - if (Flags.isCallable()) - Callables[Name] = SymbolAliasMapEntry(Name, Flags); - else - NonCallables[Name] = SymbolAliasMapEntry(Name, Flags); - } }); + for (auto &KV : R.getSymbols()) { + auto &Name = KV.first; + auto &Flags = KV.second; + if (Flags.isCallable()) + Callables[Name] = SymbolAliasMapEntry(Name, Flags); + else + NonCallables[Name] = SymbolAliasMapEntry(Name, Flags); + } + // Create a partitioning materialization unit and lodge it with the // implementation dylib. if (auto Err = PDR.getImplDylib().define( std::make_unique<PartitioningIRMaterializationUnit>( - ES, std::move(TSM), R.getVModuleKey(), *this))) { + ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), + *this))) { ES.reportError(std::move(Err)); R.failMaterialization(); return; @@ -316,7 +315,7 @@ void CompileOnDemandLayer::emitPartition( } R.replace(std::make_unique<PartitioningIRMaterializationUnit>( - ES, std::move(TSM), R.getVModuleKey(), *this)); + ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), *this)); BaseLayer.emit(std::move(R), std::move(*ExtractedTSM)); } diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp index f5671d90420a..160e5ba50311 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/CompileUtils.cpp @@ -24,11 +24,20 @@ namespace llvm { namespace orc { +IRMaterializationUnit::ManglingOptions +irManglingOptionsFromTargetOptions(const TargetOptions &Opts) { + IRMaterializationUnit::ManglingOptions MO; + + MO.EmulatedTLS = Opts.EmulatedTLS; + + return MO; +} + /// Compile a Module to an ObjectFile. -SimpleCompiler::CompileResult SimpleCompiler::operator()(Module &M) { +Expected<SimpleCompiler::CompileResult> SimpleCompiler::operator()(Module &M) { CompileResult CachedObject = tryToLoadFromObjectCache(M); if (CachedObject) - return CachedObject; + return std::move(CachedObject); SmallVector<char, 0> ObjBufferSV; @@ -38,7 +47,8 @@ SimpleCompiler::CompileResult SimpleCompiler::operator()(Module &M) { legacy::PassManager PM; MCContext *Ctx; if (TM.addPassesToEmitMC(PM, Ctx, ObjStream)) - llvm_unreachable("Target does not support MC emission."); + return make_error<StringError>("Target does not support MC emission", + inconvertibleErrorCode()); PM.run(M); } @@ -47,14 +57,11 @@ SimpleCompiler::CompileResult SimpleCompiler::operator()(Module &M) { auto Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); - if (Obj) { - notifyObjectCompiled(M, *ObjBuffer); - return std::move(ObjBuffer); - } + if (!Obj) + return Obj.takeError(); - // TODO: Actually report errors helpfully. - consumeError(Obj.takeError()); - return nullptr; + notifyObjectCompiled(M, *ObjBuffer); + return std::move(ObjBuffer); } SimpleCompiler::CompileResult @@ -73,9 +80,11 @@ void SimpleCompiler::notifyObjectCompiled(const Module &M, ConcurrentIRCompiler::ConcurrentIRCompiler(JITTargetMachineBuilder JTMB, ObjectCache *ObjCache) - : JTMB(std::move(JTMB)), ObjCache(ObjCache) {} + : IRCompiler(irManglingOptionsFromTargetOptions(JTMB.getOptions())), + JTMB(std::move(JTMB)), ObjCache(ObjCache) {} -std::unique_ptr<MemoryBuffer> ConcurrentIRCompiler::operator()(Module &M) { +Expected<std::unique_ptr<MemoryBuffer>> +ConcurrentIRCompiler::operator()(Module &M) { auto TM = cantFail(JTMB.createTargetMachine()); SimpleCompiler C(*TM, ObjCache); return C(M); diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Core.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Core.cpp index 63ef889dae46..ec706cf63d35 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -468,15 +468,19 @@ Error MaterializationResponsibility::notifyEmitted() { } Error MaterializationResponsibility::defineMaterializing( - const SymbolFlagsMap &NewSymbolFlags) { - // Add the given symbols to this responsibility object. - // It's ok if we hit a duplicate here: In that case the new version will be - // discarded, and the JITDylib::defineMaterializing method will return a - // duplicate symbol error. - for (auto &KV : NewSymbolFlags) - SymbolFlags.insert(KV); + SymbolFlagsMap NewSymbolFlags) { - return JD.defineMaterializing(NewSymbolFlags); + LLVM_DEBUG({ + dbgs() << "In " << JD.getName() << " defining materializing symbols " + << NewSymbolFlags << "\n"; + }); + if (auto AcceptedDefs = JD.defineMaterializing(std::move(NewSymbolFlags))) { + // Add all newly accepted symbols to this responsibility object. + for (auto &KV : *AcceptedDefs) + SymbolFlags.insert(KV); + return Error::success(); + } else + return AcceptedDefs.takeError(); } void MaterializationResponsibility::failMaterialization() { @@ -809,31 +813,52 @@ void JITDylib::removeGenerator(DefinitionGenerator &G) { }); } -Error JITDylib::defineMaterializing(const SymbolFlagsMap &SymbolFlags) { - return ES.runSessionLocked([&]() -> Error { +Expected<SymbolFlagsMap> +JITDylib::defineMaterializing(SymbolFlagsMap SymbolFlags) { + + return ES.runSessionLocked([&]() -> Expected<SymbolFlagsMap> { std::vector<SymbolTable::iterator> AddedSyms; + std::vector<SymbolFlagsMap::iterator> RejectedWeakDefs; - for (auto &KV : SymbolFlags) { - SymbolTable::iterator EntryItr; - bool Added; + for (auto SFItr = SymbolFlags.begin(), SFEnd = SymbolFlags.end(); + SFItr != SFEnd; ++SFItr) { - std::tie(EntryItr, Added) = - Symbols.insert(std::make_pair(KV.first, SymbolTableEntry(KV.second))); + auto &Name = SFItr->first; + auto &Flags = SFItr->second; - if (Added) { - AddedSyms.push_back(EntryItr); - EntryItr->second.setState(SymbolState::Materializing); - } else { - // Remove any symbols already added. - for (auto &SI : AddedSyms) - Symbols.erase(SI); + auto EntryItr = Symbols.find(Name); - // FIXME: Return all duplicates. - return make_error<DuplicateDefinition>(*KV.first); - } + // If the entry already exists... + if (EntryItr != Symbols.end()) { + + // If this is a strong definition then error out. + if (!Flags.isWeak()) { + // Remove any symbols already added. + for (auto &SI : AddedSyms) + Symbols.erase(SI); + + // FIXME: Return all duplicates. + return make_error<DuplicateDefinition>(*Name); + } + + // Otherwise just make a note to discard this symbol after the loop. + RejectedWeakDefs.push_back(SFItr); + continue; + } else + EntryItr = + Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first; + + AddedSyms.push_back(EntryItr); + EntryItr->second.setState(SymbolState::Materializing); } - return Error::success(); + // Remove any rejected weak definitions from the SymbolFlags map. + while (!RejectedWeakDefs.empty()) { + SymbolFlags.erase(RejectedWeakDefs.back()); + RejectedWeakDefs.pop_back(); + } + + return SymbolFlags; }); } diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp index d311f34179c7..023940dc8298 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp @@ -11,9 +11,14 @@ namespace llvm { namespace orc { +IRCompileLayer::IRCompiler::~IRCompiler() {} + IRCompileLayer::IRCompileLayer(ExecutionSession &ES, ObjectLayer &BaseLayer, - CompileFunction Compile) - : IRLayer(ES), BaseLayer(BaseLayer), Compile(std::move(Compile)) {} + std::unique_ptr<IRCompiler> Compile) + : IRLayer(ES, ManglingOpts), BaseLayer(BaseLayer), + Compile(std::move(Compile)) { + ManglingOpts = &this->Compile->getManglingOptions(); +} void IRCompileLayer::setNotifyCompiled(NotifyCompiledFunction NotifyCompiled) { std::lock_guard<std::mutex> Lock(IRLayerMutex); @@ -24,7 +29,7 @@ void IRCompileLayer::emit(MaterializationResponsibility R, ThreadSafeModule TSM) { assert(TSM && "Module must not be null"); - if (auto Obj = TSM.withModuleDo(Compile)) { + if (auto Obj = TSM.withModuleDo(*Compile)) { { std::lock_guard<std::mutex> Lock(IRLayerMutex); if (NotifyCompiled) diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp index 845ecc71eb87..511248f83b25 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp @@ -12,10 +12,10 @@ namespace llvm { namespace orc { -IRTransformLayer::IRTransformLayer(ExecutionSession &ES, - IRLayer &BaseLayer, - TransformFunction Transform) - : IRLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} +IRTransformLayer::IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer, + TransformFunction Transform) + : IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer), + Transform(std::move(Transform)) {} void IRTransformLayer::emit(MaterializationResponsibility R, ThreadSafeModule TSM) { diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 54473ab46423..6189056b3d9f 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -96,8 +96,10 @@ LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) { auto ObjLinkingLayer = std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr)); - if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) + if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) { ObjLinkingLayer->setOverrideObjectFlagsWithResponsibilityFlags(true); + ObjLinkingLayer->setAutoClaimResponsibilityForObjectSymbols(true); + } // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence // errors from some GCC / libstdc++ bots. Remove this conversion (i.e. @@ -105,7 +107,7 @@ LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) { return std::unique_ptr<ObjectLayer>(std::move(ObjLinkingLayer)); } -Expected<IRCompileLayer::CompileFunction> +Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> LLJIT::createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB) { @@ -116,13 +118,13 @@ LLJIT::createCompileFunction(LLJITBuilderState &S, // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler, // depending on the number of threads requested. if (S.NumCompileThreads > 0) - return ConcurrentIRCompiler(std::move(JTMB)); + return std::make_unique<ConcurrentIRCompiler>(std::move(JTMB)); auto TM = JTMB.createTargetMachine(); if (!TM) return TM.takeError(); - return TMOwningSimpleCompiler(std::move(*TM)); + return std::make_unique<TMOwningSimpleCompiler>(std::move(*TM)); } LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Layer.cpp index 580e2682ec8c..ebc7801f11ff 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Layer.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/Orc/Layer.h" +#include "llvm/IR/Constants.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" @@ -15,15 +16,15 @@ namespace llvm { namespace orc { -IRLayer::IRLayer(ExecutionSession &ES) : ES(ES) {} IRLayer::~IRLayer() {} Error IRLayer::add(JITDylib &JD, ThreadSafeModule TSM, VModuleKey K) { return JD.define(std::make_unique<BasicIRLayerMaterializationUnit>( - *this, std::move(K), std::move(TSM))); + *this, *getManglingOptions(), std::move(TSM), std::move(K))); } IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES, + const ManglingOptions &MO, ThreadSafeModule TSM, VModuleKey K) : MaterializationUnit(SymbolFlagsMap(), std::move(K)), TSM(std::move(TSM)) { @@ -32,12 +33,44 @@ IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES, MangleAndInterner Mangle(ES, this->TSM.getModuleUnlocked()->getDataLayout()); this->TSM.withModuleDo([&](Module &M) { for (auto &G : M.global_values()) { - if (G.hasName() && !G.isDeclaration() && !G.hasLocalLinkage() && - !G.hasAvailableExternallyLinkage() && !G.hasAppendingLinkage()) { - auto MangledName = Mangle(G.getName()); - SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G); - SymbolToDefinition[MangledName] = &G; + // Skip globals that don't generate symbols. + if (!G.hasName() || G.isDeclaration() || G.hasLocalLinkage() || + G.hasAvailableExternallyLinkage() || G.hasAppendingLinkage()) + continue; + + // thread locals generate different symbols depending on whether or not + // emulated TLS is enabled. + if (G.isThreadLocal() && MO.EmulatedTLS) { + auto &GV = cast<GlobalVariable>(G); + + auto Flags = JITSymbolFlags::fromGlobalValue(GV); + + auto EmuTLSV = Mangle(("__emutls_v." + GV.getName()).str()); + SymbolFlags[EmuTLSV] = Flags; + SymbolToDefinition[EmuTLSV] = &GV; + + // If this GV has a non-zero initializer we'll need to emit an + // __emutls.t symbol too. + if (GV.hasInitializer()) { + const auto *InitVal = GV.getInitializer(); + + // Skip zero-initializers. + if (isa<ConstantAggregateZero>(InitVal)) + continue; + const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal); + if (InitIntValue && InitIntValue->isZero()) + continue; + + auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str()); + SymbolFlags[EmuTLST] = Flags; + } + continue; } + + // Otherwise we just need a normal linker mangling. + auto MangledName = Mangle(G.getName()); + SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G); + SymbolToDefinition[MangledName] = &G; } }); } @@ -72,8 +105,8 @@ void IRMaterializationUnit::discard(const JITDylib &JD, } BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( - IRLayer &L, VModuleKey K, ThreadSafeModule TSM) - : IRMaterializationUnit(L.getExecutionSession(), std::move(TSM), + IRLayer &L, const ManglingOptions &MO, ThreadSafeModule TSM, VModuleKey K) + : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM), std::move(K)), L(L), K(std::move(K)) {} diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp index a92264c0be14..ff8289a264c8 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" +#include "llvm/Object/COFF.h" namespace { @@ -160,6 +161,39 @@ Error RTDyldObjectLinkingLayer::onObjLoad( std::set<StringRef> &InternalSymbols) { SymbolFlagsMap ExtraSymbolsToClaim; SymbolMap Symbols; + + // Hack to support COFF constant pool comdats introduced during compilation: + // (See http://llvm.org/PR40074) + if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(&Obj)) { + auto &ES = getExecutionSession(); + + // For all resolved symbols that are not already in the responsibilty set: + // check whether the symbol is in a comdat section and if so mark it as + // weak. + for (auto &Sym : COFFObj->symbols()) { + if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) + continue; + auto Name = Sym.getName(); + if (!Name) + return Name.takeError(); + auto I = Resolved.find(*Name); + + // Skip unresolved symbols, internal symbols, and symbols that are + // already in the responsibility set. + if (I == Resolved.end() || InternalSymbols.count(*Name) || + R.getSymbols().count(ES.intern(*Name))) + continue; + auto Sec = Sym.getSection(); + if (!Sec) + return Sec.takeError(); + if (*Sec == COFFObj->section_end()) + continue; + auto &COFFSec = *COFFObj->getCOFFSection(**Sec); + if (COFFSec.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT) + I->second.setFlags(I->second.getFlags() | JITSymbolFlags::Weak); + } + } + for (auto &KV : Resolved) { // Scan the symbols and add them to the Symbols map for resolution. @@ -184,10 +218,17 @@ Error RTDyldObjectLinkingLayer::onObjLoad( Symbols[InternedName] = JITEvaluatedSymbol(KV.second.getAddress(), Flags); } - if (!ExtraSymbolsToClaim.empty()) + if (!ExtraSymbolsToClaim.empty()) { if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim)) return Err; + // If we claimed responsibility for any weak symbols but were rejected then + // we need to remove them from the resolved set. + for (auto &KV : ExtraSymbolsToClaim) + if (KV.second.isWeak() && !R.getSymbols().count(KV.first)) + Symbols.erase(KV.first); + } + if (auto Err = R.notifyResolved(Symbols)) { R.failMaterialization(); return Err; |