X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=tools%2Flli%2FOrcLazyJIT.h;h=2b2db6e668cc60de448a19c79b787424d050b8e6;hp=e323714646b72e0d1977b14261e4429e5584da37;hb=a1c91277c445c3a9d9101629d157af4c6a9b46b0;hpb=96bdb6594ca63946e9755aec25d42dfd904d0e97 diff --git a/tools/lli/OrcLazyJIT.h b/tools/lli/OrcLazyJIT.h index e323714646b..2b2db6e668c 100644 --- a/tools/lli/OrcLazyJIT.h +++ b/tools/lli/OrcLazyJIT.h @@ -18,7 +18,9 @@ #include "llvm/ADT/Triple.h" #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" #include "llvm/ExecutionEngine/Orc/CompileUtils.h" +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" +#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" @@ -32,13 +34,16 @@ public: typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr; typedef orc::ObjectLinkingLayer<> ObjLayerT; typedef orc::IRCompileLayer CompileLayerT; - typedef orc::LazyEmittingLayer LazyEmitLayerT; + typedef std::function(std::unique_ptr)> + TransformFtor; + typedef orc::IRTransformLayer IRDumpLayerT; + typedef orc::LazyEmittingLayer LazyEmitLayerT; typedef orc::CompileOnDemandLayer CODLayerT; typedef CODLayerT::ModuleSetHandleT ModuleHandleT; typedef std::function< - std::unique_ptr(CompileLayerT&, + std::unique_ptr(IRDumpLayerT&, RuntimeDyld::MemoryManager&, LLVMContext&)> CallbackManagerBuilder; @@ -51,24 +56,74 @@ public: Mang(this->TM->getDataLayout()), ObjectLayer(), CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), - LazyEmitLayer(CompileLayer), - CCMgr(BuildCallbackMgr(CompileLayer, CCMgrMemMgr, Context)), - CODLayer(LazyEmitLayer, *CCMgr) { } + IRDumpLayer(CompileLayer, createDebugDumper()), + LazyEmitLayer(IRDumpLayer), + CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)), + CODLayer(LazyEmitLayer, *CCMgr), + CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {} + + ~OrcLazyJIT() { + // Run any destructors registered with __cxa_atexit. + CXXRuntimeOverrides.runDestructors(); + // Run any IR destructors. + for (auto &DtorRunner : IRStaticDestructorRunners) + DtorRunner.runViaLayer(CODLayer); + } + + template + static PtrTy fromTargetAddress(orc::TargetAddress Addr) { + return reinterpret_cast(static_cast(Addr)); + } ModuleHandleT addModule(std::unique_ptr M) { // Attach a data-layout if one isn't already present. if (M->getDataLayout().isDefault()) M->setDataLayout(*TM->getDataLayout()); + // Record the static constructors and destructors. We have to do this before + // we hand over ownership of the module to the JIT. + std::vector CtorNames, DtorNames; + for (auto Ctor : orc::getConstructors(*M)) + CtorNames.push_back(mangle(Ctor.Func->getName())); + for (auto Dtor : orc::getDestructors(*M)) + DtorNames.push_back(mangle(Dtor.Func->getName())); + + // Symbol resolution order: + // 1) Search the JIT symbols. + // 2) Check for C++ runtime overrides. + // 3) Search the host process (LLI)'s symbol table. + auto Resolver = + orc::createLambdaResolver( + [this](const std::string &Name) { + + if (auto Sym = CODLayer.findSymbol(Name, true)) + return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags()); + + if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name)) + return Sym; + + if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) + return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported); + + return RuntimeDyld::SymbolInfo(nullptr); + }, + [](const std::string &Name) { return RuntimeDyld::SymbolInfo(nullptr); } + ); + + // Add the module to the JIT. std::vector> S; S.push_back(std::move(M)); - auto FallbackLookup = - [](const std::string &Name) { - if (auto Addr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) - return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported); - return RuntimeDyld::SymbolInfo(nullptr); - }; - return CODLayer.addModuleSet(std::move(S), std::move(FallbackLookup)); + auto H = CODLayer.addModuleSet(std::move(S), nullptr, std::move(Resolver)); + + // Run the static constructors, and save the static destructor runner for + // execution when the JIT is torn down. + orc::CtorDtorRunner CtorRunner(std::move(CtorNames), H); + CtorRunner.runViaLayer(CODLayer); + + IRStaticDestructorRunners.push_back( + orc::CtorDtorRunner(std::move(DtorNames), H)); + + return H; } orc::JITSymbol findSymbol(const std::string &Name) { @@ -90,15 +145,21 @@ private: return MangledName; } + static TransformFtor createDebugDumper(); + std::unique_ptr TM; Mangler Mang; SectionMemoryManager CCMgrMemMgr; ObjLayerT ObjectLayer; CompileLayerT CompileLayer; + IRDumpLayerT IRDumpLayer; LazyEmitLayerT LazyEmitLayer; std::unique_ptr CCMgr; CODLayerT CODLayer; + + orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides; + std::vector> IRStaticDestructorRunners; }; int runOrcLazyJIT(std::unique_ptr M, int ArgC, char* ArgV[]);