diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/Orc')
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/Core.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp | 95 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h | 33 |
4 files changed, 110 insertions, 27 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index bae4977f36a..2fb2e5f4f98 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -869,7 +869,7 @@ VSO &ExecutionSession::createVSO(std::string Name) { }); } -Expected<SymbolMap> lookup(const std::vector<VSO *> &VSOs, SymbolNameSet Names) { +Expected<SymbolMap> lookup(const VSO::VSOList &VSOs, SymbolNameSet Names) { #if LLVM_ENABLE_THREADS // In the threaded case we use promises to return the results. std::promise<SymbolMap> PromisedResult; @@ -975,7 +975,7 @@ Expected<SymbolMap> lookup(const std::vector<VSO *> &VSOs, SymbolNameSet Names) } /// Look up a symbol by searching a list of VSOs. -Expected<JITEvaluatedSymbol> lookup(const std::vector<VSO *> VSOs, +Expected<JITEvaluatedSymbol> lookup(const VSO::VSOList &VSOs, SymbolStringPtr Name) { SymbolNameSet Names({Name}); if (auto ResultMap = lookup(VSOs, std::move(Names))) { diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index 08aa3a8ce52..4aa5f3badec 100644 --- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -13,38 +13,123 @@ #include "llvm/ExecutionEngine/Orc/OrcABISupport.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/Support/Format.h" #include "llvm/Transforms/Utils/Cloning.h" #include <sstream> +using namespace llvm; +using namespace llvm::orc; + +namespace { + +class CompileCallbackMaterializationUnit : public orc::MaterializationUnit { +public: + using CompileFunction = JITCompileCallbackManager::CompileFunction; + + CompileCallbackMaterializationUnit(SymbolStringPtr Name, + CompileFunction Compile) + : MaterializationUnit(SymbolFlagsMap({{Name, JITSymbolFlags::Exported}})), + Name(std::move(Name)), Compile(std::move(Compile)) {} + +private: + void materialize(MaterializationResponsibility R) { + SymbolMap Result; + Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported); + R.resolve(Result); + R.finalize(); + } + + void discard(const VSO &V, SymbolStringPtr Name) { + llvm_unreachable("Discard should never occur on a LMU?"); + } + + SymbolStringPtr Name; + CompileFunction Compile; +}; + +} // namespace + namespace llvm { namespace orc { void JITCompileCallbackManager::anchor() {} void IndirectStubsManager::anchor() {} +Expected<JITTargetAddress> +JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) { + if (auto TrampolineAddr = getAvailableTrampolineAddr()) { + auto CallbackName = ES.getSymbolStringPool().intern( + std::string("cc") + std::to_string(++NextCallbackId)); + + std::lock_guard<std::mutex> Lock(CCMgrMutex); + AddrToSymbol[*TrampolineAddr] = CallbackName; + cantFail( + CallbacksVSO.define(make_unique<CompileCallbackMaterializationUnit>( + std::move(CallbackName), std::move(Compile)))); + return *TrampolineAddr; + } else + return TrampolineAddr.takeError(); +} + +JITTargetAddress JITCompileCallbackManager::executeCompileCallback( + JITTargetAddress TrampolineAddr) { + SymbolStringPtr Name; + + { + std::unique_lock<std::mutex> Lock(CCMgrMutex); + auto I = AddrToSymbol.find(TrampolineAddr); + + // If this address is not associated with a compile callback then report an + // error to the execution session and return ErrorHandlerAddress to the + // callee. + if (I == AddrToSymbol.end()) { + Lock.unlock(); + std::string ErrMsg; + { + raw_string_ostream ErrMsgStream(ErrMsg); + ErrMsgStream << "No compile callback for trampoline at " + << format("0x%016x", TrampolineAddr); + } + ES.reportError( + make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode())); + return ErrorHandlerAddress; + } else + Name = I->second; + } + + if (auto Sym = lookup({&CallbacksVSO}, Name)) + return Sym->getAddress(); + else { + // If anything goes wrong materializing Sym then report it to the session + // and return the ErrorHandlerAddress; + ES.reportError(Sym.takeError()); + return ErrorHandlerAddress; + } +} + std::unique_ptr<JITCompileCallbackManager> -createLocalCompileCallbackManager(const Triple &T, +createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress) { switch (T.getArch()) { default: return nullptr; case Triple::aarch64: { typedef orc::LocalJITCompileCallbackManager<orc::OrcAArch64> CCMgrT; - return llvm::make_unique<CCMgrT>(ErrorHandlerAddress); + return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress); } case Triple::x86: { typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT; - return llvm::make_unique<CCMgrT>(ErrorHandlerAddress); + return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress); } case Triple::x86_64: { if ( T.getOS() == Triple::OSType::Win32 ) { typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT; - return llvm::make_unique<CCMgrT>(ErrorHandlerAddress); + return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress); } else { typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_SysV> CCMgrT; - return llvm::make_unique<CCMgrT>(ErrorHandlerAddress); + return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress); } } diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp index 09ad3e6b11c..d6005d24a64 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp +++ b/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp @@ -18,12 +18,11 @@ LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) { Triple T(TM2->getTargetTriple()); - auto CompileCallbackMgr = orc::createLocalCompileCallbackManager(T, 0); auto IndirectStubsMgrBuilder = orc::createLocalIndirectStubsManagerBuilder(T); - OrcCBindingsStack *JITStack = new OrcCBindingsStack( - *TM2, std::move(CompileCallbackMgr), IndirectStubsMgrBuilder); + OrcCBindingsStack *JITStack = + new OrcCBindingsStack(*TM2, std::move(IndirectStubsMgrBuilder)); return wrap(JITStack); } diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h index 984adbae1b8..fd35ec46015 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -200,12 +200,10 @@ private: }; public: - OrcCBindingsStack(TargetMachine &TM, - std::unique_ptr<CompileCallbackMgr> CCMgr, IndirectStubsManagerBuilder IndirectStubsMgrBuilder) - : DL(TM.createDataLayout()), - IndirectStubsMgr(IndirectStubsMgrBuilder()), CCMgr(std::move(CCMgr)), + : CCMgr(createLocalCompileCallbackManager(TM.getTargetTriple(), ES, 0)), + DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()), ObjectLayer(ES, [this](orc::VModuleKey K) { auto ResolverI = Resolvers.find(K); @@ -216,13 +214,14 @@ public: return ObjLayerT::Resources{ std::make_shared<SectionMemoryManager>(), Resolver}; }, - nullptr, - [this](orc::VModuleKey K, const object::ObjectFile &Obj, const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { + nullptr, + [this](orc::VModuleKey K, const object::ObjectFile &Obj, + const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { this->notifyFinalized(K, Obj, LoadedObjInfo); - }, - [this](orc::VModuleKey K, const object::ObjectFile &Obj) { + }, + [this](orc::VModuleKey K, const object::ObjectFile &Obj) { this->notifyFreed(K, Obj); - }), + }), CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)), CODLayer(ES, CompileLayer, [this](orc::VModuleKey K) { @@ -270,15 +269,15 @@ public: createLazyCompileCallback(JITTargetAddress &RetAddr, LLVMOrcLazyCompileCallbackFn Callback, void *CallbackCtx) { - if (auto CCInfoOrErr = CCMgr->getCompileCallback()) { - auto &CCInfo = *CCInfoOrErr; - CCInfo.setCompileAction([=]() -> JITTargetAddress { - return Callback(wrap(this), CallbackCtx); - }); - RetAddr = CCInfo.getAddress(); + auto WrappedCallback = [=]() -> JITTargetAddress { + return Callback(wrap(this), CallbackCtx); + }; + + if (auto CCAddr = CCMgr->getCompileCallback(std::move(WrappedCallback))) { + RetAddr = *CCAddr; return LLVMOrcErrSuccess; } else - return mapError(CCInfoOrErr.takeError()); + return mapError(CCAddr.takeError()); } LLVMOrcErrorCode createIndirectStub(StringRef StubName, @@ -484,6 +483,7 @@ private: } orc::ExecutionSession ES; + std::unique_ptr<CompileCallbackMgr> CCMgr; std::vector<JITEventListener *> EventListeners; @@ -492,7 +492,6 @@ private: std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr; - std::unique_ptr<CompileCallbackMgr> CCMgr; ObjLayerT ObjectLayer; CompileLayerT CompileLayer; CODLayerT CODLayer; |