diff --git a/include/serene/context.h b/include/serene/context.h index 710cb84..3ea4e0a 100644 --- a/include/serene/context.h +++ b/include/serene/context.h @@ -78,6 +78,7 @@ class SERENE_EXPORT SereneContext { bool JITenableObjectCache = true; bool JITenableGDBNotificationListener = true; bool JITenablePerfNotificationListener = true; + bool JITLazy = false; Options() = default; }; diff --git a/include/serene/jit/halley.h b/include/serene/jit/halley.h index 2b1457c..828106b 100644 --- a/include/serene/jit/halley.h +++ b/include/serene/jit/halley.h @@ -93,6 +93,8 @@ class SERENE_EXPORT Halley { std::shared_ptr activeNS; + bool isLazy = false; + public: Halley(serene::SereneContext &ctx, llvm::orc::JITTargetMachineBuilder &&jtmb, llvm::DataLayout &&dl); @@ -101,6 +103,7 @@ public: static MaybeJIT make(serene::SereneContext &ctx, llvm::orc::JITTargetMachineBuilder &&jtmb); + void setEngine(std::unique_ptr e, bool isLazy); /// Looks up a packed-argument function with the given name and returns a /// pointer to it. Propagates errors in case of failure. // llvm::Expected lookup(llvm::StringRef name) const; diff --git a/src/libserene/jit/halley.cpp b/src/libserene/jit/halley.cpp index d7343f4..b4d8dc8 100644 --- a/src/libserene/jit/halley.cpp +++ b/src/libserene/jit/halley.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -314,6 +315,13 @@ llvm::Optional Halley::addNS(Namespace &ns, return llvm::None; }; +void Halley::setEngine(std::unique_ptr e, bool isLazy) { + // Later on we might use different classes of JIT which might need some + // work for lazyness + engine = std::move(e); + this->isLazy = isLazy; +}; + void Halley::dumpToObjectFile(llvm::StringRef filename) { cache->dumpToObjectFile(filename); }; @@ -414,13 +422,28 @@ MaybeJIT Halley::make(SereneContext &serene_ctx, std::move(*targetMachine), jitEngine->cache.get()); }; - auto jit = - cantFail(llvm::orc::LLJITBuilder() - .setCompileFunctionCreator(compileFunctionCreator) - .setObjectLinkingLayerCreator(objectLinkingLayerCreator) - .create()); + if (serene_ctx.opts.JITLazy) { + // Setup a LLLazyJIT instance to the times that latency is important + // for example in a REPL. This way + auto jit = + cantFail(llvm::orc::LLLazyJITBuilder() + .setCompileFunctionCreator(compileFunctionCreator) + .setObjectLinkingLayerCreator(objectLinkingLayerCreator) + .create()); + jitEngine->setEngine(std::move(jit), true); - jitEngine->engine = std::move(jit); + } else { + // Setup a LLJIT instance for the times that performance is important + // and we want to compile everything as soon as possible. For instance + // when we run the JIT in the compiler + auto jit = + cantFail(llvm::orc::LLJITBuilder() + .setCompileFunctionCreator(compileFunctionCreator) + .setObjectLinkingLayerCreator(objectLinkingLayerCreator) + .create()); + + jitEngine->setEngine(std::move(jit), false); + } // Resolve symbols that are statically linked in the current process. llvm::orc::JITDylib &mainJD = jitEngine->engine->getMainJITDylib();