#ifndef JIT_H #define JIT_H #include #include #include #include #include #include #include #include #include #include #include #include namespace jit { using llvm::cantFail; using llvm::DataLayout; using llvm::Expected; using llvm::JITEvaluatedSymbol; using llvm::JITSymbolFlags; using llvm::SectionMemoryManager; using llvm::StringRef; using llvm::orc::ConcurrentIRCompiler; // using llvm::orc::DynamicLibrarySearchGenerator; using llvm::orc::ExecutionSession; using llvm::orc::ExecutorAddr; using llvm::orc::ExecutorSymbolDef; using llvm::orc::IRCompileLayer; using llvm::orc::JITDylib; using llvm::orc::JITTargetMachineBuilder; using llvm::orc::MangleAndInterner; using llvm::orc::ResourceTrackerSP; using llvm::orc::RTDyldObjectLinkingLayer; using llvm::orc::SelfExecutorProcessControl; using llvm::orc::ThreadSafeModule; // Simple JIT engine based on the KaleidoscopeJIT. // https://www.llvm.org/docs/tutorial/BuildingAJIT1.html class Jit { private: std::unique_ptr ES; DataLayout DL; MangleAndInterner Mangle; RTDyldObjectLinkingLayer ObjectLayer; IRCompileLayer CompileLayer; JITDylib& JD; public: Jit(std::unique_ptr ES, JITTargetMachineBuilder JTMB, DataLayout DL) : ES(std::move(ES)), DL(std::move(DL)), Mangle(*this->ES, this->DL), ObjectLayer(*this->ES, []() { return std::make_unique(); }), CompileLayer(*this->ES, ObjectLayer, std::make_unique(std::move(JTMB))), JD(this->ES->createBareJITDylib("main")) { // https://www.llvm.org/docs/ORCv2.html#how-to-add-process-and-library-symbols-to-jitdylibs // JD.addGenerator( // cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess( // DL.getGlobalPrefix()))); cantFail(JD.define(llvm::orc::absoluteSymbols( {{Mangle("libc_puts"), {ExecutorAddr::fromPtr(&puts), JITSymbolFlags::Exported}}}))); } ~Jit() { if (auto Err = ES->endSession()) ES->reportError(std::move(Err)); } static std::unique_ptr Create() { auto EPC = cantFail(SelfExecutorProcessControl::Create()); auto ES = std::make_unique(std::move(EPC)); JITTargetMachineBuilder JTMB( ES->getExecutorProcessControl().getTargetTriple()); auto DL = cantFail(JTMB.getDefaultDataLayoutForTarget()); return std::make_unique(std::move(ES), std::move(JTMB), std::move(DL)); } Expected addModule(ThreadSafeModule TSM) { auto RT = JD.createResourceTracker(); if (auto E = CompileLayer.add(RT, std::move(TSM))) { return E; } return RT; } Expected lookup(StringRef Name) { return ES->lookup({&JD}, Mangle(Name.str())); } }; } // namespace jit #endif